[llvm-branch-commits] [cfe-branch] r159663 - in /cfe/branches/tooling: ./ docs/ include/clang-c/ include/clang/AST/ include/clang/Analysis/Analyses/ include/clang/Basic/ include/clang/Driver/ include/clang/Frontend/ include/clang/Parse/ include/clang/Sema/ include/clang/Serialization/ include/clang/StaticAnalyzer/Core/ include/clang/StaticAnalyzer/Core/PathSensitive/ lib/AST/ lib/Analysis/ lib/Basic/ lib/CodeGen/ lib/Driver/ lib/Frontend/ lib/Headers/ lib/Lex/ lib/Parse/ lib/Sema/ lib/Serialization/ lib/StaticAnalyzer/Checker...
Manuel Klimek
klimek at google.com
Tue Jul 3 09:18:37 PDT 2012
Author: klimek
Date: Tue Jul 3 11:18:37 2012
New Revision: 159663
URL: http://llvm.org/viewvc/llvm-project?rev=159663&view=rev
Log:
Merging mainline
Added:
cfe/branches/tooling/include/clang/Sema/CodeCompleteOptions.h
- copied unchanged from r159654, cfe/trunk/include/clang/Sema/CodeCompleteOptions.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h
- copied unchanged from r159654, cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h
cfe/branches/tooling/lib/Basic/ConvertUTFWrapper.cpp
- copied unchanged from r159654, cfe/trunk/lib/Basic/ConvertUTFWrapper.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/Calls.cpp
- copied unchanged from r159654, cfe/trunk/lib/StaticAnalyzer/Core/Calls.cpp
cfe/branches/tooling/test/Analysis/blocks-no-inline.c
- copied unchanged from r159654, cfe/trunk/test/Analysis/blocks-no-inline.c
cfe/branches/tooling/test/Analysis/nonnull.m
- copied unchanged from r159654, cfe/trunk/test/Analysis/nonnull.m
cfe/branches/tooling/test/CodeCompletion/documentation.cpp
- copied unchanged from r159654, cfe/trunk/test/CodeCompletion/documentation.cpp
cfe/branches/tooling/test/Index/complete-documentation.cpp
- copied unchanged from r159654, cfe/trunk/test/Index/complete-documentation.cpp
cfe/branches/tooling/test/Index/cursor-dynamic-call.mm
- copied unchanged from r159654, cfe/trunk/test/Index/cursor-dynamic-call.mm
cfe/branches/tooling/test/PCH/chain-staticvar-instantiation.cpp
- copied unchanged from r159654, cfe/trunk/test/PCH/chain-staticvar-instantiation.cpp
cfe/branches/tooling/test/Sema/warn-self-assign-field.mm
- copied unchanged from r159654, cfe/trunk/test/Sema/warn-self-assign-field.mm
cfe/branches/tooling/test/SemaObjC/delay-parsing-cfunctions.m
- copied unchanged from r159654, cfe/trunk/test/SemaObjC/delay-parsing-cfunctions.m
Removed:
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h
cfe/branches/tooling/lib/StaticAnalyzer/Core/ObjCMessage.cpp
cfe/branches/tooling/test/Sema/warn-self-assign-memvar.mm
Modified:
cfe/branches/tooling/ (props changed)
cfe/branches/tooling/CMakeLists.txt
cfe/branches/tooling/docs/AddressSanitizer.html
cfe/branches/tooling/include/clang-c/Index.h
cfe/branches/tooling/include/clang/AST/Decl.h
cfe/branches/tooling/include/clang/AST/RawCommentList.h
cfe/branches/tooling/include/clang/Analysis/Analyses/ThreadSafety.h
cfe/branches/tooling/include/clang/Basic/ABI.h
cfe/branches/tooling/include/clang/Basic/AddressSpaces.h
cfe/branches/tooling/include/clang/Basic/AllDiagnostics.h
cfe/branches/tooling/include/clang/Basic/AttrKinds.h
cfe/branches/tooling/include/clang/Basic/Builtins.h
cfe/branches/tooling/include/clang/Basic/ConvertUTF.h
cfe/branches/tooling/include/clang/Basic/Diagnostic.h
cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td
cfe/branches/tooling/include/clang/Basic/DiagnosticIDs.h
cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td
cfe/branches/tooling/include/clang/Basic/ExceptionSpecificationType.h
cfe/branches/tooling/include/clang/Basic/ExpressionTraits.h
cfe/branches/tooling/include/clang/Basic/FileManager.h
cfe/branches/tooling/include/clang/Basic/FileSystemOptions.h
cfe/branches/tooling/include/clang/Basic/FileSystemStatCache.h
cfe/branches/tooling/include/clang/Basic/IdentifierTable.h
cfe/branches/tooling/include/clang/Basic/LLVM.h
cfe/branches/tooling/include/clang/Basic/Lambda.h
cfe/branches/tooling/include/clang/Basic/LangOptions.def
cfe/branches/tooling/include/clang/Basic/LangOptions.h
cfe/branches/tooling/include/clang/Basic/Linkage.h
cfe/branches/tooling/include/clang/Basic/MacroBuilder.h
cfe/branches/tooling/include/clang/Basic/Module.h
cfe/branches/tooling/include/clang/Basic/ObjCRuntime.h
cfe/branches/tooling/include/clang/Basic/OnDiskHashTable.h
cfe/branches/tooling/include/clang/Basic/OpenCL.h
cfe/branches/tooling/include/clang/Basic/OperatorKinds.h
cfe/branches/tooling/include/clang/Basic/PartialDiagnostic.h
cfe/branches/tooling/include/clang/Basic/PrettyStackTrace.h
cfe/branches/tooling/include/clang/Basic/SourceLocation.h
cfe/branches/tooling/include/clang/Basic/SourceManager.h
cfe/branches/tooling/include/clang/Basic/SourceManagerInternals.h
cfe/branches/tooling/include/clang/Basic/Specifiers.h
cfe/branches/tooling/include/clang/Basic/TargetBuiltins.h
cfe/branches/tooling/include/clang/Basic/TargetInfo.h
cfe/branches/tooling/include/clang/Basic/TargetOptions.h
cfe/branches/tooling/include/clang/Basic/TemplateKinds.h
cfe/branches/tooling/include/clang/Basic/TokenKinds.h
cfe/branches/tooling/include/clang/Basic/TypeTraits.h
cfe/branches/tooling/include/clang/Basic/Version.h
cfe/branches/tooling/include/clang/Basic/VersionTuple.h
cfe/branches/tooling/include/clang/Basic/Visibility.h
cfe/branches/tooling/include/clang/Driver/Arg.h
cfe/branches/tooling/include/clang/Driver/CC1Options.td
cfe/branches/tooling/include/clang/Frontend/ASTUnit.h
cfe/branches/tooling/include/clang/Frontend/CompilerInstance.h
cfe/branches/tooling/include/clang/Frontend/FrontendOptions.h
cfe/branches/tooling/include/clang/Parse/Parser.h
cfe/branches/tooling/include/clang/Sema/CodeCompleteConsumer.h
cfe/branches/tooling/include/clang/Sema/ScopeInfo.h
cfe/branches/tooling/include/clang/Sema/Sema.h
cfe/branches/tooling/include/clang/Serialization/ASTWriter.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/Checker.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
cfe/branches/tooling/lib/AST/Decl.cpp
cfe/branches/tooling/lib/AST/RawCommentList.cpp
cfe/branches/tooling/lib/Analysis/LiveVariables.cpp
cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp
cfe/branches/tooling/lib/Analysis/UninitializedValues.cpp
cfe/branches/tooling/lib/Basic/CMakeLists.txt
cfe/branches/tooling/lib/Basic/SourceManager.cpp
cfe/branches/tooling/lib/CodeGen/CGExpr.cpp
cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp
cfe/branches/tooling/lib/CodeGen/CGValue.h
cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h
cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp
cfe/branches/tooling/lib/Driver/Driver.cpp
cfe/branches/tooling/lib/Frontend/ASTUnit.cpp
cfe/branches/tooling/lib/Frontend/CompilerInstance.cpp
cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp
cfe/branches/tooling/lib/Headers/bmiintrin.h
cfe/branches/tooling/lib/Lex/LiteralSupport.cpp
cfe/branches/tooling/lib/Parse/ParseDecl.cpp
cfe/branches/tooling/lib/Parse/ParseDeclCXX.cpp
cfe/branches/tooling/lib/Parse/ParseObjc.cpp
cfe/branches/tooling/lib/Parse/Parser.cpp
cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp
cfe/branches/tooling/lib/Sema/CodeCompleteConsumer.cpp
cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp
cfe/branches/tooling/lib/Sema/SemaDecl.cpp
cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp
cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp
cfe/branches/tooling/lib/Sema/SemaExpr.cpp
cfe/branches/tooling/lib/Sema/SemaLambda.cpp
cfe/branches/tooling/lib/Sema/SemaStmt.cpp
cfe/branches/tooling/lib/Sema/SemaTemplateInstantiate.cpp
cfe/branches/tooling/lib/Serialization/ASTReader.cpp
cfe/branches/tooling/lib/Serialization/ASTWriter.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/CMakeLists.txt
cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerManager.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/ProgramState.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
cfe/branches/tooling/test/Analysis/delegates.m
cfe/branches/tooling/test/Analysis/malloc.c
cfe/branches/tooling/test/Analysis/misc-ps-region-store.m
cfe/branches/tooling/test/Analysis/new.cpp
cfe/branches/tooling/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
cfe/branches/tooling/test/Analysis/traversal-algorithm.mm
cfe/branches/tooling/test/CMakeLists.txt
cfe/branches/tooling/test/CodeGen/block-byref-aggr.c
cfe/branches/tooling/test/CodeGen/bmi-builtins.c
cfe/branches/tooling/test/CodeGenCXX/inline-functions.cpp
cfe/branches/tooling/test/Driver/crash-report.c
cfe/branches/tooling/test/Misc/warning-flags.c
cfe/branches/tooling/test/Parser/declarators.c
cfe/branches/tooling/test/Sema/uninit-variables.c
cfe/branches/tooling/test/SemaCXX/PR9460.cpp
cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp
cfe/branches/tooling/test/SemaCXX/warn-thread-safety-analysis.cpp
cfe/branches/tooling/test/SemaCXX/warn-unreachable.cpp (props changed)
cfe/branches/tooling/test/SemaObjC/blocks.m
cfe/branches/tooling/tools/c-index-test/c-index-test.c
cfe/branches/tooling/tools/libclang/CIndex.cpp
cfe/branches/tooling/tools/libclang/CIndexCodeCompletion.cpp
cfe/branches/tooling/tools/libclang/CXCursor.cpp
cfe/branches/tooling/tools/libclang/libclang.exports
Propchange: cfe/branches/tooling/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Jul 3 11:18:37 2012
@@ -1,3 +1,3 @@
/cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:146581-159509
+/cfe/trunk:146581-159654
/cfe/trunk/test/SemaTemplate:126920
Modified: cfe/branches/tooling/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/CMakeLists.txt?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/CMakeLists.txt (original)
+++ cfe/branches/tooling/CMakeLists.txt Tue Jul 3 11:18:37 2012
@@ -53,6 +53,14 @@
set(LLVM_TABLEGEN_EXE "${PATH_TO_LLVM_BUILD}/bin/Debug/llvm-tblgen${CMAKE_EXECUTABLE_SUFFIX}")
endif()
+ # Define the default arguments to use with 'lit', and an option for the user
+ # to override.
+ set(LIT_ARGS_DEFAULT "-sv")
+ if (MSVC OR XCODE)
+ set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar")
+ endif()
+ set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
+
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
Modified: cfe/branches/tooling/docs/AddressSanitizer.html
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/docs/AddressSanitizer.html?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/docs/AddressSanitizer.html (original)
+++ cfe/branches/tooling/docs/AddressSanitizer.html Tue Jul 3 11:18:37 2012
@@ -99,10 +99,10 @@
<a href="LanguageExtensions.html#__has_feature_extension">__has_feature</a>
can be used for this purpose.
<pre>
-#if defined(__has_feature) && __has_feature(address_sanitizer)
- code that runs only under AddressSanitizer
-#else
- code that does not run under AddressSanitizer
+#if defined(__has_feature)
+# if __has_feature(address_sanitizer)
+ code that builds only under AddressSanitizer
+# endif
#endif
</pre>
@@ -112,14 +112,16 @@
<a href="LanguageExtensions.html#address_sanitizer">
<tt>no_address_safety_analysis</tt></a>
to disable instrumentation of a particular function.
+This attribute may not be supported by other compilers, so we suggest to
+use it together with <tt>__has_feature(address_sanitizer)</tt>.
Note: currently, this attribute will be lost if the function is inlined.
<h2 id="platforms">Supported Platforms</h2>
AddressSanitizer is supported on
<ul><li>Linux x86_64 (tested on Ubuntu 10.04).
-<li>MacOS 10.6 i386/x86_64.
+<li>MacOS 10.6 and 10.7 (i386/x86_64).
</ul>
-Support for Linux i386/ARM and MacOS 10.7 is in progress
+Support for Linux i386/ARM is in progress
(it may work, but is not guaranteed too).
Modified: cfe/branches/tooling/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang-c/Index.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang-c/Index.h (original)
+++ cfe/branches/tooling/include/clang-c/Index.h Tue Jul 3 11:18:37 2012
@@ -1058,7 +1058,14 @@
* This option can be used to search for declarations/definitions while
* ignoring the usages.
*/
- CXTranslationUnit_SkipFunctionBodies = 0x40
+ CXTranslationUnit_SkipFunctionBodies = 0x40,
+
+ /**
+ * \brief Used to indicate that brief documentation comments should be
+ * included into the set of code completions returned from this translation
+ * unit.
+ */
+ CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 0x80
};
/**
@@ -3137,6 +3144,19 @@
CINDEX_LINKAGE int clang_Cursor_getObjCSelectorIndex(CXCursor);
/**
+ * \brief Given a cursor pointing to a C++ method call or an ObjC message,
+ * returns non-zero if the method/message is "dynamic", meaning:
+ *
+ * For a C++ method: the call is virtual.
+ * For an ObjC message: the receiver is an object instance, not 'super' or a
+ * specific class.
+ *
+ * If the method/message is "static" or the cursor does not point to a
+ * method/message, it will return zero.
+ */
+CINDEX_LINKAGE int clang_Cursor_isDynamicCall(CXCursor C);
+
+/**
* \brief Given a cursor that represents a declaration, return the associated
* comment's source range. The range may include multiple consecutive comments
* with whitespace in between.
@@ -3786,6 +3806,14 @@
CINDEX_LINKAGE CXString
clang_getCompletionParent(CXCompletionString completion_string,
enum CXCursorKind *kind);
+
+/**
+ * \brief Retrieve the brief documentation comment attached to the declaration
+ * that corresponds to the given completion string.
+ */
+CINDEX_LINKAGE CXString
+clang_getCompletionBriefComment(CXCompletionString completion_string);
+
/**
* \brief Retrieve a completion string for an arbitrary declaration or macro
* definition cursor.
@@ -3836,7 +3864,13 @@
* \brief Whether to include code patterns for language constructs
* within the set of code completions, e.g., for loops.
*/
- CXCodeComplete_IncludeCodePatterns = 0x02
+ CXCodeComplete_IncludeCodePatterns = 0x02,
+
+ /**
+ * \brief Whether to include brief documentation within the set of code
+ * completions returned.
+ */
+ CXCodeComplete_IncludeBriefComments = 0x04
};
/**
Modified: cfe/branches/tooling/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/Decl.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/Decl.h (original)
+++ cfe/branches/tooling/include/clang/AST/Decl.h Tue Jul 3 11:18:37 2012
@@ -2151,6 +2151,16 @@
}
unsigned getBitWidthValue(const ASTContext &Ctx) const;
+ /// setBitWidth - Set the bit-field width for this member.
+ // Note: used by some clients (i.e., do not remove it).
+ void setBitWidth(Expr *Width);
+ /// removeBitWidth - Remove the bit-field width from this member.
+ // Note: used by some clients (i.e., do not remove it).
+ void removeBitWidth() {
+ assert(isBitField() && "no bitfield width to remove");
+ InitializerOrBitWidth.setPointer(0);
+ }
+
/// getInClassInitStyle - Get the kind of (C++11) in-class initializer which
/// this field has.
InClassInitStyle getInClassInitStyle() const {
Modified: cfe/branches/tooling/include/clang/AST/RawCommentList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/RawCommentList.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/RawCommentList.h (original)
+++ cfe/branches/tooling/include/clang/AST/RawCommentList.h Tue Jul 3 11:18:37 2012
@@ -92,7 +92,7 @@
unsigned getBeginLine(const SourceManager &SM) const;
unsigned getEndLine(const SourceManager &SM) const;
- StringRef getBriefText(const ASTContext &Context) const {
+ const char *getBriefText(const ASTContext &Context) const {
if (BriefTextValid)
return BriefText;
@@ -103,7 +103,7 @@
SourceRange Range;
mutable StringRef RawText;
- mutable StringRef BriefText;
+ mutable const char *BriefText;
mutable bool RawTextValid : 1; ///< True if RawText is valid
mutable bool BriefTextValid : 1; ///< True if BriefText is valid
@@ -129,7 +129,7 @@
StringRef getRawTextSlow(const SourceManager &SourceMgr) const;
- StringRef extractBriefText(const ASTContext &Context) const;
+ const char *extractBriefText(const ASTContext &Context) const;
friend class ASTReader;
};
Modified: cfe/branches/tooling/include/clang/Analysis/Analyses/ThreadSafety.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Analysis/Analyses/ThreadSafety.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Analysis/Analyses/ThreadSafety.h (original)
+++ cfe/branches/tooling/include/clang/Analysis/Analyses/ThreadSafety.h Tue Jul 3 11:18:37 2012
@@ -60,7 +60,8 @@
enum LockErrorKind {
LEK_LockedSomeLoopIterations,
LEK_LockedSomePredecessors,
- LEK_LockedAtEndOfFunction
+ LEK_LockedAtEndOfFunction,
+ LEK_NotLockedAtEndOfFunction
};
/// Handler class for thread safety warnings.
Modified: cfe/branches/tooling/include/clang/Basic/ABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/ABI.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/ABI.h (original)
+++ cfe/branches/tooling/include/clang/Basic/ABI.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// These enums/classes describe ABI related information about constructors,
-// destructors and thunks.
-//
+///
+/// \file
+/// \brief Enums/classes describing ABI related information about constructors,
+/// destructors and thunks.
+///
//===----------------------------------------------------------------------===//
#ifndef CLANG_BASIC_ABI_H
@@ -19,27 +20,27 @@
namespace clang {
-/// CXXCtorType - C++ constructor types
+/// \brief C++ constructor types.
enum CXXCtorType {
- Ctor_Complete, // Complete object ctor
- Ctor_Base, // Base object ctor
- Ctor_CompleteAllocating // Complete object allocating ctor
+ Ctor_Complete, ///< Complete object ctor
+ Ctor_Base, ///< Base object ctor
+ Ctor_CompleteAllocating ///< Complete object allocating ctor
};
-/// CXXDtorType - C++ destructor types
+/// \brief C++ destructor types.
enum CXXDtorType {
- Dtor_Deleting, // Deleting dtor
- Dtor_Complete, // Complete object dtor
- Dtor_Base // Base object dtor
+ Dtor_Deleting, ///< Deleting dtor
+ Dtor_Complete, ///< Complete object dtor
+ Dtor_Base ///< Base object dtor
};
-/// ReturnAdjustment - A return adjustment.
+/// \brief A return adjustment.
struct ReturnAdjustment {
- /// NonVirtual - The non-virtual adjustment from the derived object to its
+ /// \brief The non-virtual adjustment from the derived object to its
/// nearest virtual base.
int64_t NonVirtual;
- /// VBaseOffsetOffset - The offset (in bytes), relative to the address point
+ /// \brief The offset (in bytes), relative to the address point
/// of the virtual base class offset.
int64_t VBaseOffsetOffset;
@@ -63,13 +64,13 @@
}
};
-/// ThisAdjustment - A 'this' pointer adjustment.
+/// \brief A \c this pointer adjustment.
struct ThisAdjustment {
- /// NonVirtual - The non-virtual adjustment from the derived object to its
+ /// \brief The non-virtual adjustment from the derived object to its
/// nearest virtual base.
int64_t NonVirtual;
- /// VCallOffsetOffset - The offset (in bytes), relative to the address point,
+ /// \brief The offset (in bytes), relative to the address point,
/// of the virtual call offset.
int64_t VCallOffsetOffset;
@@ -93,13 +94,13 @@
}
};
-/// ThunkInfo - The 'this' pointer adjustment as well as an optional return
+/// \brief The \c this pointer adjustment as well as an optional return
/// adjustment for a thunk.
struct ThunkInfo {
- /// This - The 'this' pointer adjustment.
+ /// \brief The \c this pointer adjustment.
ThisAdjustment This;
- /// Return - The return adjustment.
+ /// \brief The return adjustment.
ReturnAdjustment Return;
ThunkInfo() { }
Modified: cfe/branches/tooling/include/clang/Basic/AddressSpaces.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/AddressSpaces.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/AddressSpaces.h (original)
+++ cfe/branches/tooling/include/clang/Basic/AddressSpaces.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file provides definitions for the various language-specific address
-// spaces.
-//
+///
+/// \file
+/// \brief Provides definitions for the various language-specific address
+/// spaces.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_ADDRESSSPACES_H
@@ -19,8 +20,9 @@
namespace LangAS {
-/// This enum defines the set of possible language-specific address spaces.
-/// It uses a high starting offset so as not to conflict with any address
+/// \brief Defines the set of possible language-specific address spaces.
+///
+/// This uses a high starting offset so as not to conflict with any address
/// space used by a target.
enum ID {
Offset = 0xFFFF00,
Modified: cfe/branches/tooling/include/clang/Basic/AllDiagnostics.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/AllDiagnostics.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/AllDiagnostics.h (original)
+++ cfe/branches/tooling/include/clang/Basic/AllDiagnostics.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file includes all the separate Diagnostic headers & some related
-// helpers.
-//
+///
+/// \file
+/// \brief Includes all the separate Diagnostic headers & some related helpers.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ALL_DIAGNOSTICS_H
Modified: cfe/branches/tooling/include/clang/Basic/AttrKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/AttrKinds.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/AttrKinds.h (original)
+++ cfe/branches/tooling/include/clang/Basic/AttrKinds.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the attr::Kind enum
-//
+///
+/// \file
+/// \brief Defines the clang::attr::Kind enum.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ATTRKINDS_H
@@ -18,7 +19,7 @@
namespace attr {
-// Kind - This is a list of all the recognized kinds of attributes.
+// \brief A list of all the recognized kinds of attributes.
enum Kind {
#define ATTR(X) X,
#define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X,
Modified: cfe/branches/tooling/include/clang/Basic/Builtins.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Builtins.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Builtins.h (original)
+++ cfe/branches/tooling/include/clang/Basic/Builtins.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines enum values for all the target-independent builtin
-// functions.
-//
+///
+/// \file
+/// \brief Defines enum values for all the target-independent builtin
+/// functions.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_BUILTINS_H
@@ -56,7 +57,7 @@
bool operator!=(const Info &RHS) const { return !(*this == RHS); }
};
-/// Builtin::Context - This holds information about target-independent and
+/// \brief Holds information about both target-independent and
/// target-specific builtins, allowing easy queries by clients.
class Context {
const Info *TSRecords;
@@ -67,7 +68,7 @@
/// \brief Perform target-specific initialization
void InitializeTarget(const TargetInfo &Target);
- /// InitializeBuiltins - Mark the identifiers for all the builtins with their
+ /// \brief Mark the identifiers for all the builtins with their
/// appropriate builtin ID # and mark any non-portable builtin identifiers as
/// such.
void InitializeBuiltins(IdentifierTable &Table, const LangOptions& LangOpts);
@@ -76,39 +77,39 @@
void GetBuiltinNames(SmallVectorImpl<const char *> &Names,
bool NoBuiltins);
- /// Builtin::GetName - Return the identifier name for the specified builtin,
+ /// \brief Return the identifier name for the specified builtin,
/// e.g. "__builtin_abs".
const char *GetName(unsigned ID) const {
return GetRecord(ID).Name;
}
- /// GetTypeString - Get the type descriptor string for the specified builtin.
+ /// \brief Get the type descriptor string for the specified builtin.
const char *GetTypeString(unsigned ID) const {
return GetRecord(ID).Type;
}
- /// isConst - Return true if this function has no side effects and doesn't
+ /// \brief Return true if this function has no side effects and doesn't
/// read memory.
bool isConst(unsigned ID) const {
return strchr(GetRecord(ID).Attributes, 'c') != 0;
}
- /// isNoThrow - Return true if we know this builtin never throws an exception.
+ /// \brief Return true if we know this builtin never throws an exception.
bool isNoThrow(unsigned ID) const {
return strchr(GetRecord(ID).Attributes, 'n') != 0;
}
- /// isNoReturn - Return true if we know this builtin never returns.
+ /// \brief Return true if we know this builtin never returns.
bool isNoReturn(unsigned ID) const {
return strchr(GetRecord(ID).Attributes, 'r') != 0;
}
- /// isReturnsTwice - Return true if we know this builtin can return twice.
+ /// \brief Return true if we know this builtin can return twice.
bool isReturnsTwice(unsigned ID) const {
return strchr(GetRecord(ID).Attributes, 'j') != 0;
}
- /// isLibFunction - Return true if this is a builtin for a libc/libm function,
+ /// \brief Return true if this is a builtin for a libc/libm function,
/// with a "__builtin_" prefix (e.g. __builtin_abs).
bool isLibFunction(unsigned ID) const {
return strchr(GetRecord(ID).Attributes, 'F') != 0;
@@ -146,10 +147,10 @@
/// argument and whether this function as a va_list argument.
bool isScanfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg);
- /// isConstWithoutErrno - Return true if this function has no side
- /// effects and doesn't read memory, except for possibly errno. Such
- /// functions can be const when the MathErrno lang option is
- /// disabled.
+ /// \brief Return true if this function has no side effects and doesn't
+ /// read memory, except for possibly errno.
+ ///
+ /// Such functions can be const when the MathErrno lang option is disabled.
bool isConstWithoutErrno(unsigned ID) const {
return strchr(GetRecord(ID).Attributes, 'e') != 0;
}
Modified: cfe/branches/tooling/include/clang/Basic/ConvertUTF.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/ConvertUTF.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/ConvertUTF.h (original)
+++ cfe/branches/tooling/include/clang/Basic/ConvertUTF.h Tue Jul 3 11:18:37 2012
@@ -159,6 +159,25 @@
#ifdef __cplusplus
}
+
+/*************************************************************************/
+/* Below are LLVM-specific wrappers of the functions above. */
+
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+
+/**
+ * Convert an UTF8 StringRef to UTF8, UTF16, or UTF32 depending on
+ * WideCharWidth. The converted data is written to ResultPtr, which needs to
+ * point to at least WideCharWidth * (Source.Size() + 1) bytes. On success,
+ * ResultPtr will point one after the end of the copied string.
+ * \return true on success.
+ */
+bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
+ char *&ResultPtr);
+
+}
#endif
#endif
Modified: cfe/branches/tooling/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Diagnostic.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Diagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Basic/Diagnostic.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the Diagnostic-related interfaces.
-//
+///
+/// \file
+/// \brief Defines the Diagnostic-related interfaces.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_DIAGNOSTIC_H
@@ -82,7 +83,7 @@
}
/// \brief Create a code modification hint that inserts the given
- /// code from \arg FromRange at a specific location.
+ /// code from \p FromRange at a specific location.
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc,
CharSourceRange FromRange,
bool BeforePreviousInsertions = false) {
@@ -121,14 +122,15 @@
}
};
-/// DiagnosticsEngine - This concrete class is used by the front-end to report
-/// problems and issues. It massages the diagnostics (e.g. handling things like
-/// "report warnings as errors" and passes them off to the DiagnosticConsumer
-/// for reporting to the user. DiagnosticsEngine is tied to one translation unit
-/// and one SourceManager.
+/// \brief Concrete class used by the front-end to report problems and issues.
+///
+/// This massages the diagnostics (e.g. handling things like "report warnings
+/// as errors" and passes them off to the DiagnosticConsumer for reporting to
+/// the user. DiagnosticsEngine is tied to one translation unit and one
+/// SourceManager.
class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
public:
- /// Level - The level of the diagnostic, after it has been through mapping.
+ /// \brief The level of the diagnostic, after it has been through mapping.
enum Level {
Ignored = DiagnosticIDs::Ignored,
Note = DiagnosticIDs::Note,
@@ -137,35 +139,36 @@
Fatal = DiagnosticIDs::Fatal
};
- /// ExtensionHandling - How do we handle otherwise-unmapped extension? This
- /// is controlled by -pedantic and -pedantic-errors.
+ /// \brief How do we handle otherwise-unmapped extension?
+ ///
+ /// This is controlled by -pedantic and -pedantic-errors.
enum ExtensionHandling {
Ext_Ignore, Ext_Warn, Ext_Error
};
enum ArgumentKind {
- ak_std_string, // std::string
- ak_c_string, // const char *
- ak_sint, // int
- ak_uint, // unsigned
- ak_identifierinfo, // IdentifierInfo
- ak_qualtype, // QualType
- ak_declarationname, // DeclarationName
- ak_nameddecl, // NamedDecl *
- ak_nestednamespec, // NestedNameSpecifier *
- ak_declcontext, // DeclContext *
- ak_qualtype_pair // pair<QualType, QualType>
+ ak_std_string, ///< std::string
+ ak_c_string, ///< const char *
+ ak_sint, ///< int
+ ak_uint, ///< unsigned
+ ak_identifierinfo, ///< IdentifierInfo
+ ak_qualtype, ///< QualType
+ ak_declarationname, ///< DeclarationName
+ ak_nameddecl, ///< NamedDecl *
+ ak_nestednamespec, ///< NestedNameSpecifier *
+ ak_declcontext, ///< DeclContext *
+ ak_qualtype_pair ///< pair<QualType, QualType>
};
- /// Specifies which overload candidates to display when overload resolution
- /// fails.
+ /// \brief Specifies which overload candidates to display when overload
+ /// resolution fails.
enum OverloadsShown {
Ovl_All, ///< Show all overloads.
Ovl_Best ///< Show just the "best" overload candidates.
};
- /// ArgumentValue - This typedef represents on argument value, which is a
- /// union discriminated by ArgumentKind, with a value.
+ /// \brief Represents on argument value, which is a union discriminated
+ /// by ArgumentKind, with a value.
typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
private:
@@ -191,12 +194,13 @@
bool OwnsDiagClient;
SourceManager *SourceMgr;
- /// \brief Mapping information for diagnostics. Mapping info is
- /// packed into four bits per diagnostic. The low three bits are the mapping
- /// (an instance of diag::Mapping), or zero if unset. The high bit is set
- /// when the mapping was established as a user mapping. If the high bit is
- /// clear, then the low bits are set to the default value, and should be
- /// mapped with -pedantic, -Werror, etc.
+ /// \brief Mapping information for diagnostics.
+ ///
+ /// Mapping info is packed into four bits per diagnostic. The low three
+ /// bits are the mapping (an instance of diag::Mapping), or zero if unset.
+ /// The high bit is set when the mapping was established as a user mapping.
+ /// If the high bit is clear, then the low bits are set to the default
+ /// value, and should be mapped with -pedantic, -Werror, etc.
///
/// A new DiagState is created and kept around when diagnostic pragmas modify
/// the state so that we know what is the diagnostic state at any given
@@ -224,8 +228,10 @@
std::list<DiagState> DiagStates;
/// \brief Represents a point in source where the diagnostic state was
- /// modified because of a pragma. 'Loc' can be null if the point represents
- /// the diagnostic state modifications done through the command-line.
+ /// modified because of a pragma.
+ ///
+ /// 'Loc' can be null if the point represents the diagnostic state
+ /// modifications done through the command-line.
struct DiagStatePoint {
DiagState *State;
FullSourceLoc Loc;
@@ -243,9 +249,11 @@
}
};
- /// \brief A vector of all DiagStatePoints representing changes in diagnostic
- /// state due to diagnostic pragmas. The vector is always sorted according to
- /// the SourceLocation of the DiagStatePoint.
+ /// \brief A sorted vector of all DiagStatePoints representing changes in
+ /// diagnostic state due to diagnostic pragmas.
+ ///
+ /// The vector is always sorted according to the SourceLocation of the
+ /// DiagStatePoint.
typedef std::vector<DiagStatePoint> DiagStatePointsTy;
mutable DiagStatePointsTy DiagStatePoints;
@@ -275,9 +283,10 @@
/// the given source location.
DiagStatePointsTy::iterator GetDiagStatePointForLoc(SourceLocation Loc) const;
- /// ErrorOccurred / FatalErrorOccurred - This is set to true when an error or
- /// fatal error is emitted, and is sticky.
+ /// \brief Sticky flag set to \c true when an error is emitted.
bool ErrorOccurred;
+
+ /// \brief Sticky flag set to \c true when a fatal error is emitted.
bool FatalErrorOccurred;
/// \brief Indicates that an unrecoverable error has occurred.
@@ -288,18 +297,20 @@
unsigned TrapNumErrorsOccurred;
unsigned TrapNumUnrecoverableErrorsOccurred;
- /// LastDiagLevel - This is the level of the last diagnostic emitted. This is
- /// used to emit continuation diagnostics with the same level as the
+ /// \brief The level of the last diagnostic emitted.
+ ///
+ /// This is used to emit continuation diagnostics with the same level as the
/// diagnostic that they follow.
DiagnosticIDs::Level LastDiagLevel;
- unsigned NumWarnings; // Number of warnings reported
- unsigned NumErrors; // Number of errors reported
- unsigned NumErrorsSuppressed; // Number of errors suppressed
-
- /// ArgToStringFn - A function pointer that converts an opaque diagnostic
- /// argument to a strings. This takes the modifiers and argument that was
- /// present in the diagnostic.
+ unsigned NumWarnings; ///< Number of warnings reported
+ unsigned NumErrors; ///< Number of errors reported
+ unsigned NumErrorsSuppressed; ///< Number of errors suppressed
+
+ /// \brief A function pointer that converts an opaque diagnostic
+ /// argument to a strings.
+ ///
+ /// This takes the modifiers and argument that was present in the diagnostic.
///
/// The PrevArgs array (whose length is NumPrevArgs) indicates the previous
/// arguments formatted for this diagnostic. Implementations of this function
@@ -365,14 +376,15 @@
// how diagnostics are emitted.
//
- /// pushMappings - Copies the current DiagMappings and pushes the new copy
+ /// \brief Copies the current DiagMappings and pushes the new copy
/// onto the top of the stack.
void pushMappings(SourceLocation Loc);
- /// popMappings - Pops the current DiagMappings off the top of the stack
- /// causing the new top of the stack to be the active mappings. Returns
- /// true if the pop happens, false if there is only one DiagMapping on the
- /// stack.
+ /// \brief Pops the current DiagMappings off the top of the stack,
+ /// causing the new top of the stack to be the active mappings.
+ ///
+ /// \returns \c true if the pop happens, \c false if there is only one
+ /// DiagMapping on the stack.
bool popMappings(SourceLocation Loc);
/// \brief Set the diagnostic client associated with this diagnostic object.
@@ -381,8 +393,10 @@
/// ownership of \c client.
void setClient(DiagnosticConsumer *client, bool ShouldOwnClient = true);
- /// setErrorLimit - Specify a limit for the number of errors we should
- /// emit before giving up. Zero disables the limit.
+ /// \brief Specify a limit for the number of errors we should
+ /// emit before giving up.
+ ///
+ /// Zero disables the limit.
void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; }
/// \brief Specify the maximum number of template instantiation
@@ -409,29 +423,28 @@
return ConstexprBacktraceLimit;
}
- /// setIgnoreAllWarnings - When set to true, any unmapped warnings are
- /// ignored. If this and WarningsAsErrors are both set, then this one wins.
+ /// \brief When set to true, any unmapped warnings are ignored.
+ ///
+ /// If this and WarningsAsErrors are both set, then this one wins.
void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }
bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; }
- /// setEnableAllWarnings - When set to true, any unmapped ignored warnings
- /// are no longer ignored. If this and IgnoreAllWarnings are both set,
- /// then that one wins.
+ /// \brief When set to true, any unmapped ignored warnings are no longer
+ /// ignored.
+ ///
+ /// If this and IgnoreAllWarnings are both set, then that one wins.
void setEnableAllWarnings(bool Val) { EnableAllWarnings = Val; }
bool getEnableAllWarnngs() const { return EnableAllWarnings; }
- /// setWarningsAsErrors - When set to true, any warnings reported are issued
- /// as errors.
+ /// \brief When set to true, any warnings reported are issued as errors.
void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
bool getWarningsAsErrors() const { return WarningsAsErrors; }
- /// setErrorsAsFatal - When set to true, any error reported is made a
- /// fatal error.
+ /// \brief When set to true, any error reported is made a fatal error.
void setErrorsAsFatal(bool Val) { ErrorsAsFatal = Val; }
bool getErrorsAsFatal() const { return ErrorsAsFatal; }
- /// setSuppressSystemWarnings - When set to true mask warnings that
- /// come from system headers.
+ /// \brief When set to true mask warnings that come from system headers.
void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
@@ -459,29 +472,34 @@
bool getShowColors() { return ShowColors; }
/// \brief Specify which overload candidates to show when overload resolution
- /// fails. By default, we show all candidates.
+ /// fails.
+ ///
+ /// By default, we show all candidates.
void setShowOverloads(OverloadsShown Val) {
ShowOverloads = Val;
}
OverloadsShown getShowOverloads() const { return ShowOverloads; }
- /// \brief Pretend that the last diagnostic issued was ignored. This can
- /// be used by clients who suppress diagnostics themselves.
+ /// \brief Pretend that the last diagnostic issued was ignored.
+ ///
+ /// This can be used by clients who suppress diagnostics themselves.
void setLastDiagnosticIgnored() {
LastDiagLevel = DiagnosticIDs::Ignored;
}
- /// setExtensionHandlingBehavior - This controls whether otherwise-unmapped
- /// extension diagnostics are mapped onto ignore/warning/error. This
- /// corresponds to the GCC -pedantic and -pedantic-errors option.
+ /// \brief Controls whether otherwise-unmapped extension diagnostics are
+ /// mapped onto ignore/warning/error.
+ ///
+ /// This corresponds to the GCC -pedantic and -pedantic-errors option.
void setExtensionHandlingBehavior(ExtensionHandling H) {
ExtBehavior = H;
}
ExtensionHandling getExtensionHandlingBehavior() const { return ExtBehavior; }
- /// AllExtensionsSilenced - This is a counter bumped when an __extension__
- /// block is encountered. When non-zero, all extension diagnostics are
- /// entirely silenced, no matter how they are mapped.
+ /// \brief Counter bumped when an __extension__ block is/ encountered.
+ ///
+ /// When non-zero, all extension diagnostics are entirely silenced, no
+ /// matter how they are mapped.
void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; }
void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
@@ -667,9 +685,9 @@
enum {
/// \brief The maximum number of arguments we can hold.
///
- /// We currently
- /// only support up to 10 arguments (%0-%9). A single diagnostic with more
- /// than that almost certainly has to be simplified anyway.
+ /// We currently only support up to 10 arguments (%0-%9). A single
+ /// diagnostic with more than that almost certainly has to be simplified
+ /// anyway.
MaxArguments = 10,
/// \brief The maximum number of ranges we can hold.
@@ -686,12 +704,14 @@
/// \brief The number of hints in the DiagFixItHints array.
unsigned char NumDiagFixItHints;
- /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
- /// values, with one for each argument. This specifies whether the argument
- /// is in DiagArgumentsStr or in DiagArguments.
+ /// \brief Specifies whether an argument is in DiagArgumentsStr or
+ /// in DiagArguments.
+ ///
+ /// This is an array of ArgumentKind::ArgumentKind enum values, one for each
+ /// argument.
unsigned char DiagArgumentsKind[MaxArguments];
- /// \brief holds the values of each string argument for the current
+ /// \brief Holds the values of each string argument for the current
/// diagnostic.
///
/// This is only used when the corresponding ArgumentKind is ak_std_string.
@@ -779,7 +799,7 @@
return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors;
}
- // Set to initial state of "no errors occurred".
+ /// \brief Set to initial state of "no errors occurred".
void reset() {
NumErrors = Diag.TrapNumErrorsOccurred;
NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred;
@@ -889,9 +909,13 @@
Emit();
}
- /// Operator bool: conversion of DiagnosticBuilder to bool always returns
- /// true. This allows is to be used in boolean error contexts like:
+ /// \brief Conversion of DiagnosticBuilder to bool always returns \c true.
+ ///
+ /// This allows is to be used in boolean error contexts (where \c true is
+ /// used to indicate that an error has occurred), like:
+ /// \code
/// return Diag(...);
+ /// \endcode
operator bool() const { return true; }
void AddString(StringRef S) const {
@@ -1028,61 +1052,71 @@
unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
- /// getArgKind - Return the kind of the specified index. Based on the kind
- /// of argument, the accessors below can be used to get the value.
+ /// \brief Return the kind of the specified index.
+ ///
+ /// Based on the kind of argument, the accessors below can be used to get
+ /// the value.
+ ///
+ /// \pre Idx < getNumArgs()
DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const {
assert(Idx < getNumArgs() && "Argument index out of range!");
return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
}
- /// getArgStdStr - Return the provided argument string specified by Idx.
+ /// \brief Return the provided argument string specified by \p Idx.
+ /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_std_string
const std::string &getArgStdStr(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string &&
"invalid argument accessor!");
return DiagObj->DiagArgumentsStr[Idx];
}
- /// getArgCStr - Return the specified C string argument.
+ /// \brief Return the specified C string argument.
+ /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_c_string
const char *getArgCStr(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string &&
"invalid argument accessor!");
return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
}
- /// getArgSInt - Return the specified signed integer argument.
+ /// \brief Return the specified signed integer argument.
+ /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_sint
int getArgSInt(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&
"invalid argument accessor!");
return (int)DiagObj->DiagArgumentsVal[Idx];
}
- /// getArgUInt - Return the specified unsigned integer argument.
+ /// \brief Return the specified unsigned integer argument.
+ /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_uint
unsigned getArgUInt(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&
"invalid argument accessor!");
return (unsigned)DiagObj->DiagArgumentsVal[Idx];
}
- /// getArgIdentifier - Return the specified IdentifierInfo argument.
+ /// \brief Return the specified IdentifierInfo argument.
+ /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo
const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo &&
"invalid argument accessor!");
return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
}
- /// getRawArg - Return the specified non-string argument in an opaque form.
+ /// \brief Return the specified non-string argument in an opaque form.
+ /// \pre getArgKind(Idx) != DiagnosticsEngine::ak_std_string
intptr_t getRawArg(unsigned Idx) const {
assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string &&
"invalid argument accessor!");
return DiagObj->DiagArgumentsVal[Idx];
}
- /// getNumRanges - Return the number of source ranges associated with this
- /// diagnostic.
+ /// \brief Return the number of source ranges associated with this diagnostic.
unsigned getNumRanges() const {
return DiagObj->NumDiagRanges;
}
+ /// \pre Idx < getNumRanges()
const CharSourceRange &getRange(unsigned Idx) const {
assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
return DiagObj->DiagRanges[Idx];
@@ -1106,13 +1140,14 @@
return getNumFixItHints()? DiagObj->DiagFixItHints : 0;
}
- /// FormatDiagnostic - Format this diagnostic into a string, substituting the
- /// formal arguments into the %0 slots. The result is appended onto the Str
- /// array.
+ /// \brief Format this diagnostic into a string, substituting the
+ /// formal arguments into the %0 slots.
+ ///
+ /// The result is appended onto the \p OutStr array.
void FormatDiagnostic(SmallVectorImpl<char> &OutStr) const;
- /// FormatDiagnostic - Format the given format-string into the
- /// output buffer using the arguments stored in this diagnostic.
+ /// \brief Format the given format-string into the output buffer using the
+ /// arguments stored in this diagnostic.
void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
SmallVectorImpl<char> &OutStr) const;
};
@@ -1170,12 +1205,12 @@
}
};
-/// DiagnosticConsumer - This is an abstract interface implemented by clients of
-/// the front-end, which formats and prints fully processed diagnostics.
+/// \brief Abstract interface, implemented by clients of the front-end, which
+/// formats and prints fully processed diagnostics.
class DiagnosticConsumer {
protected:
- unsigned NumWarnings; // Number of warnings reported
- unsigned NumErrors; // Number of errors reported
+ unsigned NumWarnings; ///< Number of warnings reported
+ unsigned NumErrors; ///< Number of errors reported
public:
DiagnosticConsumer() : NumWarnings(0), NumErrors(0) { }
@@ -1186,7 +1221,7 @@
virtual ~DiagnosticConsumer();
- /// BeginSourceFile - Callback to inform the diagnostic client that processing
+ /// \brief Callback to inform the diagnostic client that processing
/// of a source file is beginning.
///
/// Note that diagnostics may be emitted outside the processing of a source
@@ -1194,32 +1229,35 @@
/// diagnostics with source range information are required to only be emitted
/// in between BeginSourceFile() and EndSourceFile().
///
- /// \arg LO - The language options for the source file being processed.
- /// \arg PP - The preprocessor object being used for the source; this optional
- /// and may not be present, for example when processing AST source files.
+ /// \param LangOpts The language options for the source file being processed.
+ /// \param PP The preprocessor object being used for the source; this is
+ /// optional, e.g., it may not be present when processing AST source files.
virtual void BeginSourceFile(const LangOptions &LangOpts,
const Preprocessor *PP = 0) {}
- /// EndSourceFile - Callback to inform the diagnostic client that processing
- /// of a source file has ended. The diagnostic client should assume that any
- /// objects made available via \see BeginSourceFile() are inaccessible.
+ /// \brief Callback to inform the diagnostic client that processing
+ /// of a source file has ended.
+ ///
+ /// The diagnostic client should assume that any objects made available via
+ /// BeginSourceFile() are inaccessible.
virtual void EndSourceFile() {}
/// \brief Callback to inform the diagnostic client that processing of all
/// source files has ended.
virtual void finish() {}
- /// IncludeInDiagnosticCounts - This method (whose default implementation
- /// returns true) indicates whether the diagnostics handled by this
+ /// \brief Indicates whether the diagnostics handled by this
/// DiagnosticConsumer should be included in the number of diagnostics
/// reported by DiagnosticsEngine.
+ ///
+ /// The default implementation returns true.
virtual bool IncludeInDiagnosticCounts() const;
- /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
+ /// \brief Handle this diagnostic, reporting it to the user or
/// capturing it to a log as needed.
///
- /// Default implementation just keeps track of the total number of warnings
- /// and errors.
+ /// The default implementation just keeps track of the total number of
+ /// warnings and errors.
virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const Diagnostic &Info);
@@ -1228,8 +1266,7 @@
virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const = 0;
};
-/// IgnoringDiagConsumer - This is a diagnostic client that just ignores all
-/// diags.
+/// \brief A diagnostic client that ignores all diagnostics.
class IgnoringDiagConsumer : public DiagnosticConsumer {
virtual void anchor();
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td Tue Jul 3 11:18:37 2012
@@ -169,8 +169,8 @@
def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage]>;
def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy",
[CXX98CompatBindToTemporaryCopy]>;
-def SelfAssignmentMemvar : DiagGroup<"self-assign-memvar">;
-def SelfAssignment : DiagGroup<"self-assign", [SelfAssignmentMemvar]>;
+def SelfAssignmentField : DiagGroup<"self-assign-field">;
+def SelfAssignment : DiagGroup<"self-assign", [SelfAssignmentField]>;
def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
def Sentinel : DiagGroup<"sentinel">;
def MissingMethodReturnType : DiagGroup<"missing-method-return-type">;
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticIDs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticIDs.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticIDs.h (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticIDs.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the Diagnostic IDs-related interfaces.
-//
+///
+/// \file
+/// \brief Defines the Diagnostic IDs-related interfaces.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_DIAGNOSTICIDS_H
@@ -44,7 +45,7 @@
class CustomDiagInfo;
- /// diag::kind - All of the diagnostics that can be emitted by the frontend.
+ /// \brief All of the diagnostics that can be emitted by the frontend.
typedef unsigned kind;
// Get typedefs for common diagnostics.
@@ -111,80 +112,81 @@
/// by multiple Diagnostics for multiple translation units.
class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
public:
- /// Level - The level of the diagnostic, after it has been through mapping.
+ /// Level The level of the diagnostic, after it has been through mapping.
enum Level {
Ignored, Note, Warning, Error, Fatal
};
private:
- /// CustomDiagInfo - Information for uniquing and looking up custom diags.
+ /// \brief Information for uniquing and looking up custom diags.
diag::CustomDiagInfo *CustomDiagInfo;
public:
DiagnosticIDs();
~DiagnosticIDs();
- /// getCustomDiagID - Return an ID for a diagnostic with the specified message
- /// and level. If this is the first request for this diagnosic, it is
- /// registered and created, otherwise the existing ID is returned.
+ /// \brief Return an ID for a diagnostic with the specified message and level.
+ ///
+ /// If this is the first request for this diagnosic, it is registered and
+ /// created, otherwise the existing ID is returned.
unsigned getCustomDiagID(Level L, StringRef Message);
//===--------------------------------------------------------------------===//
// Diagnostic classification and reporting interfaces.
//
- /// getDescription - Given a diagnostic ID, return a description of the
- /// issue.
+ /// \brief Given a diagnostic ID, return a description of the issue.
StringRef getDescription(unsigned DiagID) const;
- /// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic level
- /// of the specified diagnostic ID is a Warning or Extension. This only works
- /// on builtin diagnostics, not custom ones, and is not legal to call on
- /// NOTEs.
+ /// \brief Return true if the unmapped diagnostic levelof the specified
+ /// diagnostic ID is a Warning or Extension.
+ ///
+ /// This only works on builtin diagnostics, not custom ones, and is not
+ /// legal to call on NOTEs.
static bool isBuiltinWarningOrExtension(unsigned DiagID);
/// \brief Return true if the specified diagnostic is mapped to errors by
/// default.
static bool isDefaultMappingAsError(unsigned DiagID);
- /// \brief Determine whether the given built-in diagnostic ID is a
- /// Note.
+ /// \brief Determine whether the given built-in diagnostic ID is a Note.
static bool isBuiltinNote(unsigned DiagID);
- /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
- /// ID is for an extension of some sort.
- ///
+ /// \brief Determine whether the given built-in diagnostic ID is for an
+ /// extension of some sort.
static bool isBuiltinExtensionDiag(unsigned DiagID) {
bool ignored;
return isBuiltinExtensionDiag(DiagID, ignored);
}
- /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
- /// ID is for an extension of some sort. This also returns EnabledByDefault,
- /// which is set to indicate whether the diagnostic is ignored by default (in
- /// which case -pedantic enables it) or treated as a warning/error by default.
+ /// \brief Determine whether the given built-in diagnostic ID is for an
+ /// extension of some sort, and whether it is enabled by default.
+ ///
+ /// This also returns EnabledByDefault, which is set to indicate whether the
+ /// diagnostic is ignored by default (in which case -pedantic enables it) or
+ /// treated as a warning/error by default.
///
static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
- /// getWarningOptionForDiag - Return the lowest-level warning option that
- /// enables the specified diagnostic. If there is no -Wfoo flag that controls
- /// the diagnostic, this returns null.
+ /// \brief Return the lowest-level warning option that enables the specified
+ /// diagnostic.
+ ///
+ /// If there is no -Wfoo flag that controls the diagnostic, this returns null.
static StringRef getWarningOptionForDiag(unsigned DiagID);
- /// getCategoryNumberForDiag - Return the category number that a specified
- /// DiagID belongs to, or 0 if no category.
+ /// \brief Return the category number that a specified \p DiagID belongs to,
+ /// or 0 if no category.
static unsigned getCategoryNumberForDiag(unsigned DiagID);
- /// getNumberOfCategories - Return the number of categories
+ /// \brief Return the number of diagnostic categories.
static unsigned getNumberOfCategories();
- /// getCategoryNameFromID - Given a category ID, return the name of the
- /// category.
+ /// \brief Given a category ID, return the name of the category.
static StringRef getCategoryNameFromID(unsigned CategoryID);
- /// isARCDiagnostic - Return true if a given diagnostic falls into an
- /// ARC diagnostic category;
+ /// \brief Return true if a given diagnostic falls into an ARC diagnostic
+ /// category.
static bool isARCDiagnostic(unsigned DiagID);
/// \brief Enumeration describing how the the emission of a diagnostic should
@@ -253,17 +255,16 @@
DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
const DiagnosticsEngine &Diag) const;
- /// getDiagnosticLevel - This is an internal implementation helper used when
- /// DiagClass is already known.
+ /// \brief An internal implementation helper used when \p DiagClass is
+ /// already known.
DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID,
unsigned DiagClass,
SourceLocation Loc,
const DiagnosticsEngine &Diag) const;
- /// ProcessDiag - This is the method used to report a diagnostic that is
- /// finally fully formed.
+ /// \brief Used to report a diagnostic that is finally fully formed.
///
- /// \returns true if the diagnostic was emitted, false if it was
+ /// \returns \c true if the diagnostic was emitted, \c false if it was
/// suppressed.
bool ProcessDiag(DiagnosticsEngine &Diag) const;
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td Tue Jul 3 11:18:37 2012
@@ -1775,6 +1775,9 @@
def warn_no_unlock : Warning<
"mutex '%0' is still locked at the end of function">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
+def warn_expecting_locked : Warning<
+ "expecting mutex '%0' to be locked at the end of function">,
+ InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
// FIXME: improve the error message about locks not in scope
def warn_lock_some_predecessors : Warning<
"mutex '%0' is not locked on every path through here">,
@@ -3180,7 +3183,8 @@
"'__local' variable cannot have an initializer">;
def err_block_extern_cant_init : Error<
"'extern' variable cannot have an initializer">;
-def warn_extern_init : Warning<"'extern' variable has an initializer">;
+def warn_extern_init : Warning<"'extern' variable has an initializer">,
+ InGroup<DiagGroup<"extern-initializer">>;
def err_variable_object_no_init : Error<
"variable-sized object may not be initialized">;
def err_excess_initializers : Error<
@@ -5279,9 +5283,9 @@
"unspecified (use strncmp instead)">,
InGroup<DiagGroup<"string-compare">>;
-def warn_identity_memvar_assign : Warning<
- "assigning %select{member variable|instance variable}0 to itself">,
- InGroup<SelfAssignmentMemvar>;
+def warn_identity_field_assign : Warning<
+ "assigning %select{field|instance variable}0 to itself">,
+ InGroup<SelfAssignmentField>;
// Generic selections.
def err_assoc_type_incomplete : Error<
Modified: cfe/branches/tooling/include/clang/Basic/ExceptionSpecificationType.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/ExceptionSpecificationType.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/ExceptionSpecificationType.h (original)
+++ cfe/branches/tooling/include/clang/Basic/ExceptionSpecificationType.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the ExceptionSpecificationType enumeration and various
-// utility functions.
-//
+///
+/// \file
+/// \brief Defines the ExceptionSpecificationType enumeration and various
+/// utility functions.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_EXCEPTIONSPECIFICATIONTYPE_H
#define LLVM_CLANG_BASIC_EXCEPTIONSPECIFICATIONTYPE_H
Modified: cfe/branches/tooling/include/clang/Basic/ExpressionTraits.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/ExpressionTraits.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/ExpressionTraits.h (original)
+++ cfe/branches/tooling/include/clang/Basic/ExpressionTraits.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines enumerations for expression traits intrinsics.
-//
+///
+/// \file
+/// \brief Defines enumerations for expression traits intrinsics.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_EXPRESSIONTRAITS_H
Modified: cfe/branches/tooling/include/clang/Basic/FileManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/FileManager.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/FileManager.h (original)
+++ cfe/branches/tooling/include/clang/Basic/FileManager.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the FileManager interface.
-//
+///
+/// \file
+/// \brief Defines the clang::FileManager interface and associated types.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_FILEMANAGER_H
@@ -40,9 +41,8 @@
class FileManager;
class FileSystemStatCache;
-/// DirectoryEntry - Cached information about one directory (either on
-/// the disk or in the virtual file system).
-///
+/// \brief Cached information about one directory (either on disk or in
+/// the virtual file system).
class DirectoryEntry {
const char *Name; // Name of the directory.
friend class FileManager;
@@ -51,10 +51,11 @@
const char *getName() const { return Name; }
};
-/// FileEntry - Cached information about one file (either on the disk
-/// or in the virtual file system). If the 'FD' member is valid, then
-/// this FileEntry has an open file descriptor for the file.
+/// \brief Cached information about one file (either on disk
+/// or in the virtual file system).
///
+/// If the 'FD' member is valid, then this FileEntry has an open file
+/// descriptor for the file.
class FileEntry {
const char *Name; // Name of the file.
off_t Size; // File size in bytes.
@@ -96,8 +97,7 @@
time_t getModificationTime() const { return ModTime; }
mode_t getFileMode() const { return FileMode; }
- /// getDir - Return the directory the file lives in.
- ///
+ /// \brief Return the directory the file lives in.
const DirectoryEntry *getDir() const { return Dir; }
bool operator<(const FileEntry &RHS) const {
@@ -105,10 +105,12 @@
}
};
-/// FileManager - Implements support for file system lookup, file system
-/// caching, and directory search management. This also handles more advanced
-/// properties, such as uniquing files based on "inode", so that a file with two
-/// names (e.g. symlinked) will be treated as a single file.
+/// \brief Implements support for file system lookup, file system caching,
+/// and directory search management.
+///
+/// This also handles more advanced properties, such as uniquing files based
+/// on "inode", so that a file with two names (e.g. symlinked) will be treated
+/// as a single file.
///
class FileManager : public RefCountedBase<FileManager> {
FileSystemOptions FileSystemOpts;
@@ -116,30 +118,37 @@
class UniqueDirContainer;
class UniqueFileContainer;
- /// UniqueRealDirs/UniqueRealFiles - Cache for existing real
- /// directories/files.
- ///
+ /// \brief Cache for existing real directories.
UniqueDirContainer &UniqueRealDirs;
+
+ /// \brief Cache for existing real files.
UniqueFileContainer &UniqueRealFiles;
- /// \brief The virtual directories that we have allocated. For each
- /// virtual file (e.g. foo/bar/baz.cpp), we add all of its parent
+ /// \brief The virtual directories that we have allocated.
+ ///
+ /// For each virtual file (e.g. foo/bar/baz.cpp), we add all of its parent
/// directories (foo/ and foo/bar/) here.
SmallVector<DirectoryEntry*, 4> VirtualDirectoryEntries;
/// \brief The virtual files that we have allocated.
SmallVector<FileEntry*, 4> VirtualFileEntries;
- /// SeenDirEntries/SeenFileEntries - This is a cache that maps paths
- /// to directory/file entries (either real or virtual) we have
- /// looked up. The actual Entries for real directories/files are
+ /// \brief A cache that maps paths to directory entries (either real or
+ /// virtual) we have looked up
+ ///
+ /// The actual Entries for real directories/files are
/// owned by UniqueRealDirs/UniqueRealFiles above, while the Entries
/// for virtual directories/files are owned by
/// VirtualDirectoryEntries/VirtualFileEntries above.
///
llvm::StringMap<DirectoryEntry*, llvm::BumpPtrAllocator> SeenDirEntries;
+
+ /// \brief A cache that maps paths to file entries (either real or
+ /// virtual) we have looked up.
+ ///
+ /// \see SeenDirEntries
llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator> SeenFileEntries;
- /// NextFileUID - Each FileEntry we create is assigned a unique ID #.
+ /// \brief Each FileEntry we create is assigned a unique ID #.
///
unsigned NextFileUID;
@@ -216,13 +225,13 @@
llvm::MemoryBuffer *getBufferForFile(StringRef Filename,
std::string *ErrorStr = 0);
- /// \brief get the 'stat' information for the given path.
+ /// \brief Get the 'stat' information for the given \p Path.
///
/// If the path is relative, it will be resolved against the WorkingDir of the
/// FileManager's FileSystemOptions.
bool getNoncachedStatValue(StringRef Path, struct stat &StatBuf);
- /// \brief Remove the real file Entry from the cache.
+ /// \brief Remove the real file \p Entry from the cache.
void InvalidateCache(const FileEntry* Entry);
/// \brief If path is not absolute and FileSystemOptions set the working
Modified: cfe/branches/tooling/include/clang/Basic/FileSystemOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/FileSystemOptions.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/FileSystemOptions.h (original)
+++ cfe/branches/tooling/include/clang/Basic/FileSystemOptions.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the FileSystemOptions interface.
-//
+///
+/// \file
+/// \brief Defines the clang::FileSystemOptions interface.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_FILESYSTEMOPTIONS_H
Modified: cfe/branches/tooling/include/clang/Basic/FileSystemStatCache.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/FileSystemStatCache.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/FileSystemStatCache.h (original)
+++ cfe/branches/tooling/include/clang/Basic/FileSystemStatCache.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the FileSystemStatCache interface.
-//
+///
+/// \file
+/// \brief Defines the FileSystemStatCache interface.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_FILESYSTEMSTATCACHE_H
@@ -38,9 +39,10 @@
CacheMissing ///< We know that the file doesn't exist.
};
- /// FileSystemStatCache::get - Get the 'stat' information for the specified
- /// path, using the cache to accellerate it if possible. This returns true if
- /// the path does not exist or false if it exists.
+ /// \brief Get the 'stat' information for the specified path, using the cache
+ /// to accelerate it if possible.
+ ///
+ /// \returns \c true if the path does not exist or \c false if it exists.
///
/// If FileDescriptor is non-null, then this lookup should only return success
/// for files (not directories). If it is null this lookup should only return
Modified: cfe/branches/tooling/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/IdentifierTable.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/branches/tooling/include/clang/Basic/IdentifierTable.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the IdentifierInfo, IdentifierTable, and Selector
-// interfaces.
-//
+///
+/// \file
+/// \brief Defines the clang::IdentifierInfo, clang::IdentifierTable, and
+/// clang::Selector interfaces.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
@@ -37,11 +38,11 @@
class MultiKeywordSelector; // private class used by Selector
class DeclarationName; // AST class that stores declaration names
- /// IdentifierLocPair - A simple pair of identifier info and location.
+ /// \brief A simple pair of identifier info and location.
typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
-/// IdentifierInfo - One of these records is kept for each identifier that
+/// One of these records is kept for each identifier that
/// is lexed. This contains information about whether the token was \#define'd,
/// is a language keyword, or if it is a front-end token of some sort (e.g. a
/// variable or function name). The preprocessor keeps this information in a
@@ -401,10 +402,11 @@
virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0;
};
-/// IdentifierTable - This table implements an efficient mapping from strings to
-/// IdentifierInfo nodes. It has no other purpose, but this is an
-/// extremely performance-critical piece of the code, as each occurrence of
-/// every identifier goes through here when lexed.
+/// \brief Implements an efficient mapping from strings to IdentifierInfo nodes.
+///
+/// This has no other purpose, but this is an extremely performance-critical
+/// piece of the code, as each occurrence of every identifier goes through
+/// here when lexed.
class IdentifierTable {
// Shark shows that using MallocAllocator is *much* slower than using this
// BumpPtrAllocator!
@@ -414,8 +416,8 @@
IdentifierInfoLookup* ExternalLookup;
public:
- /// IdentifierTable ctor - Create the identifier table, populating it with
- /// info about the language keywords for the language specified by LangOpts.
+ /// \brief Create the identifier table, populating it with info about the
+ /// language keywords for the language specified by \p LangOpts.
IdentifierTable(const LangOptions &LangOpts,
IdentifierInfoLookup* externalLookup = 0);
@@ -433,8 +435,8 @@
return HashTable.getAllocator();
}
- /// get - Return the identifier token info for the specified named identifier.
- ///
+ /// \brief Return the identifier token info for the specified named
+ /// identifier.
IdentifierInfo &get(StringRef Name) {
llvm::StringMapEntry<IdentifierInfo*> &Entry =
HashTable.GetOrCreateValue(Name);
@@ -508,15 +510,16 @@
iterator end() const { return HashTable.end(); }
unsigned size() const { return HashTable.size(); }
- /// PrintStats - Print some statistics to stderr that indicate how well the
+ /// \brief Print some statistics to stderr that indicate how well the
/// hashing is doing.
void PrintStats() const;
void AddKeywords(const LangOptions &LangOpts);
};
-/// ObjCMethodFamily - A family of Objective-C methods. These
-/// families have no inherent meaning in the language, but are
+/// \brief A family of Objective-C methods.
+///
+/// These families have no inherent meaning in the language, but are
/// nonetheless central enough in the existing implementations to
/// merit direct AST support. While, in theory, arbitrary methods can
/// be considered to form families, we focus here on the methods
@@ -563,11 +566,13 @@
/// InvalidObjCMethodFamily.
enum { ObjCMethodFamilyBitWidth = 4 };
-/// An invalid value of ObjCMethodFamily.
+/// \brief An invalid value of ObjCMethodFamily.
enum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 };
-/// Selector - This smart pointer class efficiently represents Objective-C
-/// method names. This class will either point to an IdentifierInfo or a
+/// \brief Smart pointer class that efficiently represents Objective-C method
+/// names.
+///
+/// This class will either point to an IdentifierInfo or a
/// MultiKeywordSelector (which is private). This enables us to optimize
/// selectors that take no arguments and selectors that take 1 argument, which
/// accounts for 78% of all selectors in Cocoa.h.
@@ -668,12 +673,12 @@
/// name was supplied.
StringRef getNameForSlot(unsigned argIndex) const;
- /// getAsString - Derive the full selector name (e.g. "foo:bar:") and return
+ /// \brief Derive the full selector name (e.g. "foo:bar:") and return
/// it as an std::string.
// FIXME: Add a print method that uses a raw_ostream.
std::string getAsString() const;
- /// getMethodFamily - Derive the conventional family of this method.
+ /// \brief Derive the conventional family of this method.
ObjCMethodFamily getMethodFamily() const {
return getMethodFamilyImpl(*this);
}
@@ -686,7 +691,7 @@
}
};
-/// SelectorTable - This table allows us to fully hide how we implement
+/// \brief This table allows us to fully hide how we implement
/// multi-keyword caching.
class SelectorTable {
void *Impl; // Actually a SelectorTableImpl
@@ -696,9 +701,10 @@
SelectorTable();
~SelectorTable();
- /// getSelector - This can create any sort of selector. NumArgs indicates
- /// whether this is a no argument selector "foo", a single argument selector
- /// "foo:" or multi-argument "foo:bar:".
+ /// \brief Can create any sort of selector.
+ ///
+ /// \p NumArgs indicates whether this is a no argument selector "foo", a
+ /// single argument selector "foo:" or multi-argument "foo:bar:".
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV);
Selector getUnarySelector(IdentifierInfo *ID) {
@@ -708,11 +714,12 @@
return Selector(ID, 0);
}
- /// Return the total amount of memory allocated for managing selectors.
+ /// \brief Return the total amount of memory allocated for managing selectors.
size_t getTotalMemory() const;
- /// constructSetterName - Return the setter name for the given
- /// identifier, i.e. "set" + Name where the initial character of Name
+ /// \brief Return the setter name for the given identifier.
+ ///
+ /// This is "set" + \p Name where the initial character of \p Name
/// has been capitalized.
static Selector constructSetterName(IdentifierTable &Idents,
SelectorTable &SelTable,
Modified: cfe/branches/tooling/include/clang/Basic/LLVM.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/LLVM.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/LLVM.h (original)
+++ cfe/branches/tooling/include/clang/Basic/LLVM.h Tue Jul 3 11:18:37 2012
@@ -7,9 +7,10 @@
//
//===----------------------------------------------------------------------===//
//
-// This file forward declares and imports various common LLVM datatypes that
-// clang wants to use unqualified.
-//
+/// \file
+/// \brief Forward declares and imports various common LLVM datatypes that
+/// clang wants to use unqualified.
+///
//===----------------------------------------------------------------------===//
#ifndef CLANG_BASIC_LLVM_H
Modified: cfe/branches/tooling/include/clang/Basic/Lambda.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Lambda.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Lambda.h (original)
+++ cfe/branches/tooling/include/clang/Basic/Lambda.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines several types used to describe C++ lambda
-// expressions that are shared between the parser and AST.
+///
+/// \file
+/// \brief Defines several types used to describe C++ lambda expressions
+/// that are shared between the parser and AST.
+///
//===----------------------------------------------------------------------===//
@@ -17,16 +19,15 @@
namespace clang {
-/// LambdaCaptureDefault - The default, if any, capture method for a
-/// lambda expression.
+/// \brief The default, if any, capture method for a lambda expression.
enum LambdaCaptureDefault {
LCD_None,
LCD_ByCopy,
LCD_ByRef
};
-/// LambdaCaptureKind - The different capture forms in a lambda
-/// introducer: 'this' or a copied or referenced variable.
+/// \brief The different capture forms in a lambda introducer: 'this' or a
+/// copied or referenced variable.
enum LambdaCaptureKind {
LCK_This,
LCK_ByCopy,
Modified: cfe/branches/tooling/include/clang/Basic/LangOptions.def
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/LangOptions.def?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/LangOptions.def (original)
+++ cfe/branches/tooling/include/clang/Basic/LangOptions.def Tue Jul 3 11:18:37 2012
@@ -149,7 +149,7 @@
ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
"signed integer overflow handling")
-BENIGN_LANGOPT(InstantiationDepth, 32, 1024,
+BENIGN_LANGOPT(InstantiationDepth, 32, 512,
"maximum template instantiation depth")
BENIGN_LANGOPT(ConstexprCallDepth, 32, 512,
"maximum constexpr call depth")
Modified: cfe/branches/tooling/include/clang/Basic/LangOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/LangOptions.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/LangOptions.h (original)
+++ cfe/branches/tooling/include/clang/Basic/LangOptions.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the LangOptions interface.
-//
+///
+/// \file
+/// \brief Defines the clang::LangOptions interface.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LANGOPTIONS_H
@@ -40,8 +41,8 @@
#include "clang/Basic/LangOptions.def"
};
-/// LangOptions - This class keeps track of the various options that can be
-/// enabled, which controls the dialect of C that is accepted.
+/// \brief Keeps track of the various options that can be
+/// enabled, which controls the dialect of C or C++ that is accepted.
class LangOptions : public RefCountedBase<LangOptions>, public LangOptionsBase {
public:
typedef clang::Visibility Visibility;
@@ -60,7 +61,9 @@
std::string ObjCConstantStringClass;
- /// The name of the handler function to be called when -ftrapv is specified.
+ /// \brief The name of the handler function to be called when -ftrapv is
+ /// specified.
+ ///
/// If none is specified, abort (GCC-compatible behaviour).
std::string OverflowHandler;
@@ -85,7 +88,7 @@
void resetNonModularOptions();
};
-/// Floating point control options
+/// \brief Floating point control options
class FPOptions {
public:
unsigned fp_contract : 1;
@@ -96,7 +99,7 @@
fp_contract(LangOpts.DefaultFPContract) {}
};
-/// OpenCL volatile options
+/// \brief OpenCL volatile options
class OpenCLOptions {
public:
#define OPENCLEXT(nm) unsigned nm : 1;
@@ -119,7 +122,6 @@
TU_Module
};
- /// \brief
} // end namespace clang
#endif
Modified: cfe/branches/tooling/include/clang/Basic/Linkage.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Linkage.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Linkage.h (original)
+++ cfe/branches/tooling/include/clang/Basic/Linkage.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the Linkage enumeration and various utility
-// functions.
-//
+///
+/// \file
+/// \brief Defines the Linkage enumeration and various utility functions.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_LINKAGE_H
#define LLVM_CLANG_BASIC_LINKAGE_H
@@ -28,8 +28,9 @@
/// translation units).
InternalLinkage,
- /// \brief External linkage within a unique namespace. From the
- /// language perspective, these entities have external
+ /// \brief External linkage within a unique namespace.
+ ///
+ /// From the language perspective, these entities have external
/// linkage. However, since they reside in an anonymous namespace,
/// their names are unique to this translation unit, which is
/// equivalent to having internal linkage from the code-generation
@@ -41,8 +42,9 @@
ExternalLinkage
};
-/// \brief A more specific kind of linkage. This is relevant to CodeGen and
-/// AST file reading.
+/// \brief A more specific kind of linkage than enum Linkage.
+///
+/// This is relevant to CodeGen and AST file reading.
enum GVALinkage {
GVA_Internal,
GVA_C99Inline,
@@ -52,8 +54,7 @@
GVA_ExplicitTemplateInstantiation
};
-/// \brief Determine whether the given linkage is semantically
-/// external.
+/// \brief Determine whether the given linkage is semantically external.
inline bool isExternalLinkage(Linkage L) {
return L == UniqueExternalLinkage || L == ExternalLinkage;
}
Modified: cfe/branches/tooling/include/clang/Basic/MacroBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/MacroBuilder.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/MacroBuilder.h (original)
+++ cfe/branches/tooling/include/clang/Basic/MacroBuilder.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the MacroBuilder utility class.
-//
+///
+/// \file
+/// \brief Defines the clang::MacroBuilder utility class.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_MACROBUILDER_H
Modified: cfe/branches/tooling/include/clang/Basic/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Module.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Module.h (original)
+++ cfe/branches/tooling/include/clang/Basic/Module.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the Module class, which describes a module in the source
-// code.
-//
+///
+/// \file
+/// \brief Defines the clang::Module class, which describes a module in the
+/// source code.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_MODULE_H
#define LLVM_CLANG_BASIC_MODULE_H
@@ -137,7 +138,7 @@
llvm::SmallVector<ExportDecl, 2> Exports;
/// \brief Describes an exported module that has not yet been resolved
- /// (perhaps because tASThe module it refers to has not yet been loaded).
+ /// (perhaps because the module it refers to has not yet been loaded).
struct UnresolvedExportDecl {
/// \brief The location of the 'export' keyword in the module map file.
SourceLocation ExportLoc;
Modified: cfe/branches/tooling/include/clang/Basic/ObjCRuntime.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/ObjCRuntime.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/ObjCRuntime.h (original)
+++ cfe/branches/tooling/include/clang/Basic/ObjCRuntime.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines types useful for describing an Objective-C runtime.
-//
+///
+/// \file
+/// \brief Defines types useful for describing an Objective-C runtime.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_OBJCRUNTIME_H
@@ -19,10 +20,10 @@
namespace clang {
-/// The basic abstraction for the target ObjC runtime.
+/// \brief The basic abstraction for the target Objective-C runtime.
class ObjCRuntime {
public:
- /// The basic Objective-C runtimes that we know about.
+ /// \brief The basic Objective-C runtimes that we know about.
enum Kind {
/// 'macosx' is the Apple-provided NeXT-derived runtime on Mac OS
/// X platforms that use the non-fragile ABI; the version is a
@@ -65,7 +66,7 @@
Kind getKind() const { return TheKind; }
const VersionTuple &getVersion() const { return Version; }
- /// Does this runtime follow the set of implied behaviors for a
+ /// \brief Does this runtime follow the set of implied behaviors for a
/// "non-fragile" ABI?
bool isNonFragile() const {
switch (getKind()) {
@@ -78,11 +79,11 @@
llvm_unreachable("bad kind");
}
- /// The inverse of isNonFragile(): does this runtiem follow the set of
+ /// The inverse of isNonFragile(): does this runtime follow the set of
/// implied behaviors for a "fragile" ABI?
bool isFragile() const { return !isNonFragile(); }
- /// Is this runtime basically of the GNU family of runtimes?
+ /// \brief Is this runtime basically of the GNU family of runtimes?
bool isGNUFamily() const {
switch (getKind()) {
case FragileMacOSX:
@@ -96,15 +97,16 @@
llvm_unreachable("bad kind");
}
- /// Is this runtime basically of the NeXT family of runtimes?
+ /// \brief Is this runtime basically of the NeXT family of runtimes?
bool isNeXTFamily() const {
// For now, this is just the inverse of isGNUFamily(), but that's
// not inherently true.
return !isGNUFamily();
}
- /// Does this runtime natively provide the ARC entrypoints? ARC
- /// cannot be directly supported on a platform that does not provide
+ /// \brief Does this runtime natively provide the ARC entrypoints?
+ ///
+ /// ARC cannot be directly supported on a platform that does not provide
/// these entrypoints, although it may be supportable via a stub
/// library.
bool hasARC() const {
@@ -122,14 +124,15 @@
llvm_unreachable("bad kind");
}
- /// Does this runtime natively provide ARC-compliant 'weak'
+ /// \brief Does this runtime natively provide ARC-compliant 'weak'
/// entrypoints?
bool hasWeak() const {
// Right now, this is always equivalent to the ARC decision.
return hasARC();
}
- /// Does this runtime directly support the subscripting methods?
+ /// \brief Does this runtime directly support the subscripting methods?
+ ///
/// This is really a property of the library, not the runtime.
bool hasSubscripting() const {
switch (getKind()) {
@@ -146,8 +149,9 @@
llvm_unreachable("bad kind");
}
- /// Does this runtime provide an objc_terminate function? This is
- /// used in handlers for exceptions during the unwind process;
+ /// \brief Does this runtime provide an objc_terminate function?
+ ///
+ /// This is used in handlers for exceptions during the unwind process;
/// without it, abort() must be used in pure ObjC files.
bool hasTerminate() const {
switch (getKind()) {
@@ -160,7 +164,7 @@
llvm_unreachable("bad kind");
}
- /// Does this runtime support weakly importing classes?
+ /// \brief Does this runtime support weakly importing classes?
bool hasWeakClassImport() const {
switch (getKind()) {
case MacOSX: return true;
@@ -172,9 +176,10 @@
llvm_unreachable("bad kind");
}
- /// Try to parse an Objective-C runtime specification from the given string.
+ /// \brief Try to parse an Objective-C runtime specification from the given
+ /// string.
///
- /// Return true on error.
+ /// \return true on error.
bool tryParse(StringRef input);
std::string getAsString() const;
Modified: cfe/branches/tooling/include/clang/Basic/OnDiskHashTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/OnDiskHashTable.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/OnDiskHashTable.h (original)
+++ cfe/branches/tooling/include/clang/Basic/OnDiskHashTable.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines facilities for reading and writing on-disk hash
-// tables.
-//
+///
+/// \file
+/// \brief Defines facilities for reading and writing on-disk hash tables.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_ON_DISK_HASH_TABLE_H
#define LLVM_CLANG_BASIC_ON_DISK_HASH_TABLE_H
Modified: cfe/branches/tooling/include/clang/Basic/OpenCL.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/OpenCL.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/OpenCL.h (original)
+++ cfe/branches/tooling/include/clang/Basic/OpenCL.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines some OpenCL-specific enums.
-//
+///
+/// \file
+/// \brief Defines some OpenCL-specific enums.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_OPENCL_H
@@ -16,7 +17,7 @@
namespace clang {
-/// Names for the OpenCL image access qualifiers (OpenCL 1.1 6.6).
+/// \brief Names for the OpenCL image access qualifiers (OpenCL 1.1 6.6).
enum OpenCLImageAccess {
CLIA_read_only = 1,
CLIA_write_only = 2,
Modified: cfe/branches/tooling/include/clang/Basic/OperatorKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/OperatorKinds.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/OperatorKinds.h (original)
+++ cfe/branches/tooling/include/clang/Basic/OperatorKinds.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines C++ overloaded operators.
-//
+///
+/// \file
+/// \brief Defines an enumeration for C++ overloaded operators.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_OPERATOR_KINDS_H
@@ -16,8 +17,8 @@
namespace clang {
-/// OverloadedOperatorKind - Enumeration specifying the different kinds of
-/// C++ overloaded operators.
+/// \brief Enumeration specifying the different kinds of C++ overloaded
+/// operators.
enum OverloadedOperatorKind {
OO_None, ///< Not an overloaded operator
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
Modified: cfe/branches/tooling/include/clang/Basic/PartialDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/PartialDiagnostic.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/PartialDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Basic/PartialDiagnostic.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file implements a partial diagnostic that can be emitted anwyhere
-// in a DiagnosticBuilder stream.
-//
+///
+/// \file
+/// \brief Implements a partial diagnostic that can be emitted anwyhere
+/// in a DiagnosticBuilder stream.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_PARTIALDIAGNOSTIC_H
@@ -37,25 +38,26 @@
Storage() : NumDiagArgs(0), NumDiagRanges(0) { }
enum {
- /// MaxArguments - The maximum number of arguments we can hold. We
+ /// \brief The maximum number of arguments we can hold. We
/// currently only support up to 10 arguments (%0-%9).
+ ///
/// A single diagnostic with more than that almost certainly has to
/// be simplified anyway.
MaxArguments = PartialDiagnostic::MaxArguments
};
- /// NumDiagArgs - This contains the number of entries in Arguments.
+ /// \brief The number of entries in Arguments.
unsigned char NumDiagArgs;
- /// NumDiagRanges - This is the number of ranges in the DiagRanges array.
+ /// \brief This is the number of ranges in the DiagRanges array.
unsigned char NumDiagRanges;
- /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
- /// values, with one for each argument. This specifies whether the argument
- /// is in DiagArgumentsStr or in DiagArguments.
+ /// \brief Specifies for each argument whether it is in DiagArgumentsStr
+ /// or in DiagArguments.
unsigned char DiagArgumentsKind[MaxArguments];
- /// DiagArgumentsVal - The values for the various substitution positions.
+ /// \brief The values for the various substitution positions.
+ ///
/// This is used when the argument is not an std::string. The specific value
/// is mangled into an intptr_t and the interpretation depends on exactly
/// what sort of argument kind it is.
@@ -65,12 +67,13 @@
/// string arguments.
std::string DiagArgumentsStr[MaxArguments];
- /// DiagRanges - The list of ranges added to this diagnostic. It currently
- /// only support 10 ranges, could easily be extended if needed.
+ /// \brief The list of ranges added to this diagnostic.
+ ///
+ /// It currently only support 10 ranges, could easily be extended if needed.
CharSourceRange DiagRanges[10];
- /// FixItHints - If valid, provides a hint with some code
- /// to insert, remove, or modify at a particular position.
+ /// \brief If valid, provides a hint with some code to insert, remove, or
+ /// modify at a particular position.
SmallVector<FixItHint, 6> FixItHints;
};
@@ -114,10 +117,10 @@
// in the sense that its bits can be safely memcpy'ed and destructed
// in the new location.
- /// DiagID - The diagnostic ID.
+ /// \brief The diagnostic ID.
mutable unsigned DiagID;
- /// DiagStorage - Storage for args and ranges.
+ /// \brief Storage for args and ranges.
mutable Storage *DiagStorage;
/// \brief Allocator used to allocate storage for this diagnostic.
Modified: cfe/branches/tooling/include/clang/Basic/PrettyStackTrace.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/PrettyStackTrace.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/PrettyStackTrace.h (original)
+++ cfe/branches/tooling/include/clang/Basic/PrettyStackTrace.h Tue Jul 3 11:18:37 2012
@@ -6,11 +6,12 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the PrettyStackTraceEntry class, which is used to make
-// crashes give more contextual information about what the program was doing
-// when it crashed.
-//
+///
+/// \file
+/// \brief Defines the PrettyStackTraceEntry class, which is used to make
+/// crashes give more contextual information about what the program was doing
+/// when it crashed.
+///
//===----------------------------------------------------------------------===//
#ifndef CLANG_BASIC_PRETTYSTACKTRACE_H
@@ -21,8 +22,8 @@
namespace clang {
- /// PrettyStackTraceLoc - If a crash happens while one of these objects are
- /// live, the message is printed out along with the specified source location.
+ /// If a crash happens while one of these objects are live, the message
+ /// is printed out along with the specified source location.
class PrettyStackTraceLoc : public llvm::PrettyStackTraceEntry {
SourceManager &SM;
SourceLocation Loc;
Modified: cfe/branches/tooling/include/clang/Basic/SourceLocation.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/SourceLocation.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/SourceLocation.h (original)
+++ cfe/branches/tooling/include/clang/Basic/SourceLocation.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the SourceLocation class.
-//
+///
+/// \file
+/// \brief Defines the clang::SourceLocation class and associated facilities.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_SOURCELOCATION_H
@@ -35,8 +36,8 @@
/// source file (MemoryBuffer) along with its \#include path and \#line data.
///
class FileID {
- /// ID - Opaque identifier, 0 is "invalid". >0 is this module, <-1 is
- /// something loaded from another module.
+ /// \brief A mostly-opaque identifier, where 0 is "invalid", >0 is
+ /// this module, and <-1 is something loaded from another module.
int ID;
public:
FileID() : ID(0) {}
@@ -185,7 +186,7 @@
return LHS.getRawEncoding() < RHS.getRawEncoding();
}
-/// SourceRange - a trival tuple used to represent a source range.
+/// \brief A trival tuple used to represent a source range.
class SourceRange {
SourceLocation B;
SourceLocation E;
@@ -212,7 +213,8 @@
}
};
-/// CharSourceRange - This class represents a character granular source range.
+/// \brief Represents a character-granular source range.
+///
/// The underlying SourceRange can either specify the starting/ending character
/// of the range, or it can specify the start or the range and the start of the
/// last token of the range (a "token range"). In the token range case, the
@@ -246,7 +248,7 @@
return getCharRange(SourceRange(B, E));
}
- /// isTokenRange - Return true if the end of this range specifies the start of
+ /// \brief Return true if the end of this range specifies the start of
/// the last token. Return false if the end of this range specifies the last
/// character in the range.
bool isTokenRange() const { return IsTokenRange; }
@@ -263,17 +265,19 @@
bool isInvalid() const { return !isValid(); }
};
-/// FullSourceLoc - A SourceLocation and its associated SourceManager. Useful
-/// for argument passing to functions that expect both objects.
+/// \brief A SourceLocation and its associated SourceManager.
+///
+/// This is useful for argument passing to functions that expect both objects.
class FullSourceLoc : public SourceLocation {
const SourceManager *SrcMgr;
public:
- /// Creates a FullSourceLoc where isValid() returns false.
+ /// \brief Creates a FullSourceLoc where isValid() returns \c false.
explicit FullSourceLoc() : SrcMgr(0) {}
explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
: SourceLocation(Loc), SrcMgr(&SM) {}
+ /// \pre This FullSourceLoc has an associated SourceManager.
const SourceManager &getManager() const {
assert(SrcMgr && "SourceManager is NULL.");
return *SrcMgr;
@@ -294,13 +298,14 @@
const llvm::MemoryBuffer* getBuffer(bool *Invalid = 0) const;
- /// getBufferData - Return a StringRef to the source buffer data for the
+ /// \brief Return a StringRef to the source buffer data for the
/// specified FileID.
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
- /// offset from the start of the buffer of the location.
+ /// \brief Decompose the specified location into a raw FileID + Offset pair.
+ ///
+ /// The first element is the FileID, the second is the offset from the
+ /// start of the buffer of the location.
std::pair<FileID, unsigned> getDecomposedLoc() const;
bool isInSystemHeader() const;
@@ -327,8 +332,9 @@
}
};
- /// Prints information about this FullSourceLoc to stderr. Useful for
- /// debugging.
+ /// \brief Prints information about this FullSourceLoc to stderr.
+ ///
+ /// This is useful for debugging.
LLVM_ATTRIBUTE_USED void dump() const;
friend inline bool
@@ -344,10 +350,11 @@
};
-/// PresumedLoc - This class represents an unpacked "presumed" location which
-/// can be presented to the user. A 'presumed' location can be modified by
-/// \#line and GNU line marker directives and is always the expansion point of
-/// a normal location.
+/// \brief Represents an unpacked "presumed" location which can be presented
+/// to the user.
+///
+/// A 'presumed' location can be modified by \#line and GNU line marker
+/// directives and is always the expansion point of a normal location.
///
/// You can get a PresumedLoc from a SourceLocation with SourceManager.
class PresumedLoc {
@@ -360,9 +367,10 @@
: Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
}
- /// isInvalid - Return true if this object is invalid or uninitialized. This
- /// occurs when created with invalid source locations or when walking off
- /// the top of a \#include stack.
+ /// \brief Return true if this object is invalid or uninitialized.
+ ///
+ /// This occurs when created with invalid source locations or when walking
+ /// off the top of a \#include stack.
bool isInvalid() const { return Filename == 0; }
bool isValid() const { return Filename != 0; }
Modified: cfe/branches/tooling/include/clang/Basic/SourceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/SourceManager.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/SourceManager.h (original)
+++ cfe/branches/tooling/include/clang/Basic/SourceManager.h Tue Jul 3 11:18:37 2012
@@ -7,9 +7,10 @@
//
//===----------------------------------------------------------------------===//
///
-/// \file Defines the SourceManager interface.
+/// \file
+/// \brief Defines the SourceManager interface.
///
-/// There are three different types of locations in a file\: a spelling
+/// There are three different types of locations in a file: a spelling
/// location, an expansion location, and a presumed location.
///
/// Given an example of:
@@ -19,7 +20,7 @@
///
/// and then later on a use of min:
/// \code
-/// \#line 17
+/// #line 17
/// return min(a, b);
/// \endcode
///
@@ -65,18 +66,20 @@
/// SourceManager implementation.
///
namespace SrcMgr {
- /// CharacteristicKind - This is used to represent whether a file or directory
- /// holds normal user code, system code, or system code which is implicitly
- /// 'extern "C"' in C++ mode. Entire directories can be tagged with this
- /// (this is maintained by DirectoryLookup and friends) as can specific
- /// FileInfos when a \#pragma system_header is seen or various other cases.
+ /// \brief Indicates whether a file or directory holds normal user code,
+ /// system code, or system code which is implicitly 'extern "C"' in C++ mode.
+ ///
+ /// Entire directories can be tagged with this (this is maintained by
+ /// DirectoryLookup and friends) as can specific FileInfos when a \#pragma
+ /// system_header is seen or in various other cases.
///
enum CharacteristicKind {
C_User, C_System, C_ExternCSystem
};
- /// ContentCache - One instance of this struct is kept for every file
- /// loaded or used. This object owns the MemoryBuffer object.
+ /// \brief One instance of this struct is kept for every file loaded or used.
+ ////
+ /// This object owns the MemoryBuffer object.
class ContentCache {
enum CCFlags {
/// \brief Whether the buffer is invalid.
@@ -96,8 +99,9 @@
/// \brief Reference to the file entry representing this ContentCache.
///
/// This reference does not own the FileEntry object.
- /// It is possible for this to be NULL if
- /// the ContentCache encapsulates an imaginary text buffer.
+ ///
+ /// It is possible for this to be NULL if the ContentCache encapsulates
+ /// an imaginary text buffer.
const FileEntry *OrigEntry;
/// \brief References the file which the contents were actually loaded from.
@@ -283,12 +287,12 @@
class ExpansionInfo {
// Really these are all SourceLocations.
- /// SpellingLoc - Where the spelling for the token can be found.
+ /// \brief Where the spelling for the token can be found.
unsigned SpellingLoc;
- /// ExpansionLocStart/ExpansionLocEnd - In a macro expansion, these
+ /// In a macro expansion, ExpansionLocStart and ExpansionLocEnd
/// indicate the start and end of the expansion. In object-like macros,
- /// these will be the same. In a function-like macro expansion, the start
+ /// they will be the same. In a function-like macro expansion, the start
/// will be the identifier and the end will be the ')'. Finally, in
/// macro-argument instantiations, the end will be 'SourceLocation()', an
/// invalid location.
@@ -349,12 +353,12 @@
///
/// Given the code:
/// \code
- /// \#define F(x) f(x)
+ /// #define F(x) f(x)
/// F(42);
/// \endcode
///
/// When expanding '\c F(42)', the '\c x' would call this with an
- /// SpellingLoc pointing at '\c 42' anad an ExpansionLoc pointing at its
+ /// SpellingLoc pointing at '\c 42' and an ExpansionLoc pointing at its
/// location in the definition of '\c F'.
static ExpansionInfo createForMacroArg(SourceLocation SpellingLoc,
SourceLocation ExpansionLoc) {
@@ -426,19 +430,22 @@
/// The cache structure is complex enough to be worth breaking out of
/// SourceManager.
class IsBeforeInTranslationUnitCache {
- /// L/R QueryFID - These are the FID's of the cached query. If these match up
- /// with a subsequent query, the result can be reused.
+ /// \brief The FileID's of the cached query.
+ ///
+ /// If these match up with a subsequent query, the result can be reused.
FileID LQueryFID, RQueryFID;
- /// \brief True if LQueryFID was created before RQueryFID. This is used
- /// to compare macro expansion locations.
+ /// \brief True if LQueryFID was created before RQueryFID.
+ ///
+ /// This is used to compare macro expansion locations.
bool IsLQFIDBeforeRQFID;
/// \brief The file found in common between the two \#include traces, i.e.,
/// the nearest common ancestor of the \#include tree.
FileID CommonFID;
- /// L/R CommonOffset - This is the offset of the previous query in CommonFID.
+ /// \brief The offset of the previous query in CommonFID.
+ ///
/// Usually, this represents the location of the \#include for QueryFID, but
/// if LQueryFID is a parent of RQueryFID (or vice versa) then these can be a
/// random token in the parent.
@@ -446,13 +453,15 @@
public:
/// \brief Return true if the currently cached values match up with
- /// the specified LHS/RHS query. If not, we can't use the cache.
+ /// the specified LHS/RHS query.
+ ///
+ /// If not, we can't use the cache.
bool isCacheValid(FileID LHS, FileID RHS) const {
return LQueryFID == LHS && RQueryFID == RHS;
}
/// \brief If the cache is valid, compute the result given the
- /// specified offsets in the LHS/RHS FID's.
+ /// specified offsets in the LHS/RHS FileID's.
bool getCachedResult(unsigned LOffset, unsigned ROffset) const {
// If one of the query files is the common file, use the offset. Otherwise,
// use the #include loc in the common file.
@@ -470,7 +479,7 @@
return LOffset < ROffset;
}
- // Set up a new query.
+ /// \brief Set up a new query.
void setQueryFIDs(FileID LHS, FileID RHS, bool isLFIDBeforeRFID) {
assert(LHS != RHS);
LQueryFID = LHS;
@@ -592,7 +601,7 @@
/// \brief Holds information for \#line directives.
///
- /// It is referenced by indices from SLocEntryTable.
+ /// This is referenced by indices from SLocEntryTable.
LineTableInfo *LineTable;
/// \brief These ivars serve as a cache used in the getLineNumber
@@ -773,7 +782,7 @@
}
/// \brief Disable overridding the contents of a file, previously enabled
- /// with \see overrideFileContents.
+ /// with #overrideFileContents.
///
/// This should be called before parsing has begun.
void disableFileContentsOverride(const FileEntry *File);
@@ -1463,15 +1472,14 @@
return getLoadedSLocEntry(static_cast<unsigned>(-ID - 2), Invalid);
}
- /// createExpansionLoc - Implements the common elements of storing an
- /// expansion info struct into the SLocEntry table and producing a source
- /// location that refers to it.
+ /// Implements the common elements of storing an expansion info struct into
+ /// the SLocEntry table and producing a source location that refers to it.
SourceLocation createExpansionLocImpl(const SrcMgr::ExpansionInfo &Expansion,
unsigned TokLength,
int LoadedID = 0,
unsigned LoadedOffset = 0);
- /// isOffsetInFileID - Return true if the specified FileID contains the
+ /// \brief Return true if the specified FileID contains the
/// specified SourceLocation offset. This is a very hot method.
inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const {
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID);
@@ -1492,9 +1500,11 @@
return SLocOffset < getSLocEntry(FileID::get(FID.ID+1)).getOffset();
}
- /// createFileID - Create a new fileID for the specified ContentCache and
- /// include position. This works regardless of whether the ContentCache
- /// corresponds to a file or some other input source.
+ /// \brief Create a new fileID for the specified ContentCache and
+ /// include position.
+ ///
+ /// This works regardless of whether the ContentCache corresponds to a
+ /// file or some other input source.
FileID createFileID(const SrcMgr::ContentCache* File,
SourceLocation IncludePos,
SrcMgr::CharacteristicKind DirCharacter,
@@ -1503,8 +1513,7 @@
const SrcMgr::ContentCache *
getOrCreateContentCache(const FileEntry *SourceFile);
- /// createMemBufferContentCache - Create a new ContentCache for the specified
- /// memory buffer.
+ /// \brief Create a new ContentCache for the specified memory buffer.
const SrcMgr::ContentCache*
createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
Modified: cfe/branches/tooling/include/clang/Basic/SourceManagerInternals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/SourceManagerInternals.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/SourceManagerInternals.h (original)
+++ cfe/branches/tooling/include/clang/Basic/SourceManagerInternals.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the implementation details of the SourceManager
-// class.
-//
+///
+/// \file
+/// \brief Defines implementation details of the clang::SourceManager class.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_SOURCEMANAGER_INTERNALS_H
@@ -27,22 +27,23 @@
//===----------------------------------------------------------------------===//
struct LineEntry {
- /// FileOffset - The offset in this file that the line entry occurs at.
+ /// \brief The offset in this file that the line entry occurs at.
unsigned FileOffset;
- /// LineNo - The presumed line number of this line entry: \#line 4.
+ /// \brief The presumed line number of this line entry: \#line 4.
unsigned LineNo;
- /// FilenameID - The ID of the filename identified by this line entry:
+ /// \brief The ID of the filename identified by this line entry:
/// \#line 4 "foo.c". This is -1 if not specified.
int FilenameID;
- /// Flags - Set the 0 if no flags, 1 if a system header,
+ /// \brief Set the 0 if no flags, 1 if a system header,
SrcMgr::CharacteristicKind FileKind;
- /// IncludeOffset - This is the offset of the virtual include stack location,
- /// which is manipulated by GNU linemarker directives. If this is 0 then
- /// there is no virtual \#includer.
+ /// \brief The offset of the virtual include stack location,
+ /// which is manipulated by GNU linemarker directives.
+ ///
+ /// If this is 0 then there is no virtual \#includer.
unsigned IncludeOffset;
static LineEntry get(unsigned Offs, unsigned Line, int Filename,
@@ -72,11 +73,11 @@
return Offset < E.FileOffset;
}
-/// LineTableInfo - This class is used to hold and unique data used to
-/// represent \#line information.
+/// \brief Used to hold and unique data used to represent \#line information.
class LineTableInfo {
- /// FilenameIDs - This map is used to assign unique IDs to filenames in
- /// \#line directives. This allows us to unique the filenames that
+ /// \brief Map used to assign unique IDs to filenames in \#line directives.
+ ///
+ /// This allows us to unique the filenames that
/// frequently reoccur and reference them with indices. FilenameIDs holds
/// the mapping from string -> ID, and FilenamesByID holds the mapping of ID
/// to string.
@@ -112,8 +113,9 @@
unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
- /// FindNearestLineEntry - Find the line entry nearest to FID that is before
- /// it. If there is no line entry before Offset in FID, return null.
+ /// \brief Find the line entry nearest to FID that is before it.
+ ///
+ /// If there is no line entry before \p Offset in \p FID, returns null.
const LineEntry *FindNearestLineEntry(FileID FID, unsigned Offset);
// Low-level access
Modified: cfe/branches/tooling/include/clang/Basic/Specifiers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Specifiers.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Specifiers.h (original)
+++ cfe/branches/tooling/include/clang/Basic/Specifiers.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines various enumerations that describe declaration and
-// type specifiers.
-//
+///
+/// \file
+/// \brief Defines various enumerations that describe declaration and
+/// type specifiers.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_SPECIFIERS_H
@@ -63,9 +64,8 @@
TST_error // erroneous type
};
- /// WrittenBuiltinSpecs - Structure that packs information about the
- /// type specifiers that were written in a particular type specifier
- /// sequence.
+ /// \brief Structure that packs information about the type specifiers that
+ /// were written in a particular type specifier sequence.
struct WrittenBuiltinSpecs {
/*DeclSpec::TST*/ unsigned Type : 5;
/*DeclSpec::TSS*/ unsigned Sign : 2;
@@ -73,9 +73,8 @@
bool ModeAttr : 1;
};
- /// AccessSpecifier - A C++ access specifier (public, private,
- /// protected), plus the special value "none" which means
- /// different things in different contexts.
+ /// \brief A C++ access specifier (public, private, protected), plus the
+ /// special value "none" which means different things in different contexts.
enum AccessSpecifier {
AS_public,
AS_protected,
@@ -83,24 +82,24 @@
AS_none
};
- /// ExprValueKind - The categorization of expression values,
- /// currently following the C++0x scheme.
+ /// \brief The categorization of expression values, currently following the
+ /// C++11 scheme.
enum ExprValueKind {
- /// An r-value expression (a pr-value in the C++0x taxonomy)
+ /// \brief An r-value expression (a pr-value in the C++11 taxonomy)
/// produces a temporary value.
VK_RValue,
- /// An l-value expression is a reference to an object with
+ /// \brief An l-value expression is a reference to an object with
/// independent storage.
VK_LValue,
- /// An x-value expression is a reference to an object with
+ /// \brief An x-value expression is a reference to an object with
/// independent storage but which can be "moved", i.e.
/// efficiently cannibalized for its resources.
VK_XValue
};
- /// A further classification of the kind of object referenced by an
+ /// \brief A further classification of the kind of object referenced by an
/// l-value or x-value.
enum ExprObjectKind {
/// An ordinary object is located at an address in memory.
@@ -112,13 +111,13 @@
/// A vector component is an element or range of elements on a vector.
OK_VectorComponent,
- /// An Objective C property is a logical field of an Objective-C
- /// object which is read and written via Objective C method calls.
+ /// An Objective-C property is a logical field of an Objective-C
+ /// object which is read and written via Objective-C method calls.
OK_ObjCProperty,
- /// An Objective C array/dictionary subscripting which reads an object
- /// or writes at the subscripted array/dictionary element via
- /// Objective C method calls.
+ /// An Objective-C array/dictionary subscripting which reads an
+ /// object or writes at the subscripted array/dictionary element via
+ /// Objective-C method calls.
OK_ObjCSubscript
};
@@ -159,12 +158,12 @@
SC_Register
};
- /// Checks whether the given storage class is legal for functions.
+ /// \brief Checks whether the given storage class is legal for functions.
inline bool isLegalForFunction(StorageClass SC) {
return SC <= SC_PrivateExtern;
}
- /// Checks whether the given storage class is legal for variables.
+ /// \brief Checks whether the given storage class is legal for variables.
inline bool isLegalForVariable(StorageClass SC) {
return true;
}
Modified: cfe/branches/tooling/include/clang/Basic/TargetBuiltins.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/TargetBuiltins.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/TargetBuiltins.h (original)
+++ cfe/branches/tooling/include/clang/Basic/TargetBuiltins.h Tue Jul 3 11:18:37 2012
@@ -6,6 +6,12 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Enumerates target-specific builtins in their own namespaces within
+/// namespace ::clang.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_TARGET_BUILTINS_H
#define LLVM_CLANG_BASIC_TARGET_BUILTINS_H
@@ -15,7 +21,7 @@
namespace clang {
- /// ARM builtins
+ /// \brief ARM builtins
namespace ARM {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
@@ -25,7 +31,7 @@
};
}
- /// PPC builtins
+ /// \brief PPC builtins
namespace PPC {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
@@ -35,7 +41,7 @@
};
}
- /// NVPTX builtins
+ /// \brief NVPTX builtins
namespace NVPTX {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
@@ -46,7 +52,7 @@
}
- /// X86 builtins
+ /// \brief X86 builtins
namespace X86 {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
@@ -56,9 +62,9 @@
};
}
- /// NeonTypeFlags - Flags to identify the types for overloaded Neon
- /// builtins. These must be kept in sync with the flags in
- /// utils/TableGen/NeonEmitter.h.
+ /// \brief Flags to identify the types for overloaded Neon builtins.
+ ///
+ /// These must be kept in sync with the flags in utils/TableGen/NeonEmitter.h.
class NeonTypeFlags {
enum {
EltTypeMask = 0xf,
@@ -96,7 +102,7 @@
bool isQuad() const { return (Flags & QuadFlag) != 0; }
};
- /// Hexagon builtins
+ /// \brief Hexagon builtins
namespace Hexagon {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
@@ -106,7 +112,7 @@
};
}
- /// Mips builtins
+ /// \brief MIPS builtins
namespace Mips {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
Modified: cfe/branches/tooling/include/clang/Basic/TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/TargetInfo.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/TargetInfo.h (original)
+++ cfe/branches/tooling/include/clang/Basic/TargetInfo.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the TargetInfo interface.
-//
+///
+/// \file
+/// \brief Defines the clang::TargetInfo interface.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
@@ -41,7 +42,7 @@
namespace Builtin { struct Info; }
-/// TargetCXXABI - The types of C++ ABIs for which we can generate code.
+/// \brief The types of C++ ABIs for which we can generate code.
enum TargetCXXABI {
/// The generic ("Itanium") C++ ABI, documented at:
/// http://www.codesourcery.com/public/cxx-abi/
@@ -57,7 +58,7 @@
CXXABI_Microsoft
};
-/// TargetInfo - This class exposes information about the current target.
+/// \brief Exposes information about the current target.
///
class TargetInfo : public RefCountedBase<TargetInfo> {
llvm::Triple Triple;
@@ -99,7 +100,7 @@
TargetInfo(const std::string &T);
public:
- /// CreateTargetInfo - Construct a target for the given options.
+ /// \brief Construct a target for the given options.
///
/// \param Opts - The options to use to initialize the target. The target may
/// modify the options to canonicalize the target feature information to match
@@ -128,8 +129,8 @@
LongDouble
};
- /// BuiltinVaListKind - The different kinds of __builtin_va_list types
- /// defined by the target implementation.
+ /// \brief The different kinds of __builtin_va_list types defined by
+ /// the target implementation.
enum BuiltinVaListKind {
/// typedef char* __builtin_va_list;
CharPtrBuiltinVaList = 0,
@@ -155,7 +156,8 @@
IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType;
- /// Flag whether the Objective-C built-in boolean type should be signed char.
+ /// \brief Whether Objective-C's built-in boolean type should be signed char.
+ ///
/// Otherwise, when this flag is not set, the normal built-in boolean type is
/// used.
unsigned UseSignedCharForObjCBool : 1;
@@ -167,10 +169,12 @@
/// boundary.
unsigned UseBitFieldTypeAlignment : 1;
- /// Control whether zero length bitfields (e.g., int : 0;) force alignment of
- /// the next bitfield. If the alignment of the zero length bitfield is
- /// greater than the member that follows it, `bar', `bar' will be aligned as
- /// the type of the zero-length bitfield.
+ /// \brief Whether zero length bitfields (e.g., int : 0;) force alignment of
+ /// the next bitfield.
+ ///
+ /// If the alignment of the zero length bitfield is greater than the member
+ /// that follows it, `bar', `bar' will be aligned as the type of the
+ /// zero-length bitfield.
unsigned UseZeroLengthBitfieldAlignment : 1;
/// If non-zero, specifies a fixed alignment value for bitfields that follow
@@ -193,19 +197,20 @@
IntType getSigAtomicType() const { return SigAtomicType; }
- /// getTypeWidth - Return the width (in bits) of the specified integer type
- /// enum. For example, SignedInt -> getIntWidth().
+ /// \brief Return the width (in bits) of the specified integer type enum.
+ ///
+ /// For example, SignedInt -> getIntWidth().
unsigned getTypeWidth(IntType T) const;
- /// getTypeAlign - Return the alignment (in bits) of the specified integer
- /// type enum. For example, SignedInt -> getIntAlign().
+ /// \brief Return the alignment (in bits) of the specified integer type enum.
+ ///
+ /// For example, SignedInt -> getIntAlign().
unsigned getTypeAlign(IntType T) const;
- /// isTypeSigned - Return whether an integer types is signed. Returns true if
- /// the type is signed; false otherwise.
+ /// \brief Returns true if the type is signed; false otherwise.
static bool isTypeSigned(IntType T);
- /// getPointerWidth - Return the width of pointers on this target, for the
+ /// \brief Return the width of pointers on this target, for the
/// specified address space.
uint64_t getPointerWidth(unsigned AddrSpace) const {
return AddrSpace == 0 ? PointerWidth : getPointerWidthV(AddrSpace);
@@ -214,17 +219,21 @@
return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace);
}
- /// getBoolWidth/Align - Return the size of '_Bool' and C++ 'bool' for this
- /// target, in bits.
+ /// \brief Return the size of '_Bool' and C++ 'bool' for this target, in bits.
unsigned getBoolWidth() const { return BoolWidth; }
+
+ /// \brief Return the alignment of '_Bool' and C++ 'bool' for this target.
unsigned getBoolAlign() const { return BoolAlign; }
unsigned getCharWidth() const { return 8; } // FIXME
unsigned getCharAlign() const { return 8; } // FIXME
- /// getShortWidth/Align - Return the size of 'signed short' and
- /// 'unsigned short' for this target, in bits.
+ /// \brief Return the size of 'signed short' and 'unsigned short' for this
+ /// target, in bits.
unsigned getShortWidth() const { return 16; } // FIXME
+
+ /// \brief Return the alignment of 'signed short' and 'unsigned short' for
+ /// this target.
unsigned getShortAlign() const { return 16; } // FIXME
/// getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for
@@ -242,7 +251,7 @@
unsigned getLongLongWidth() const { return LongLongWidth; }
unsigned getLongLongAlign() const { return LongLongAlign; }
- /// getSuitableAlign - Return the alignment that is suitable for storing any
+ /// \brief Return the alignment that is suitable for storing any
/// object with a fundamental alignment requirement.
unsigned getSuitableAlign() const { return SuitableAlign; }
@@ -284,7 +293,7 @@
return *LongDoubleFormat;
}
- /// getFloatEvalMethod - Return the value for the C99 FLT_EVAL_METHOD macro.
+ /// \brief Return the value for the C99 FLT_EVAL_METHOD macro.
virtual unsigned getFloatEvalMethod() const { return 0; }
// getLargeArrayMinWidth/Align - Return the minimum array size that is
@@ -292,21 +301,19 @@
unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; }
unsigned getLargeArrayAlign() const { return LargeArrayAlign; }
- /// getMaxAtomicPromoteWidth - Return the maximum width lock-free atomic
- /// operation which will ever be supported for the given target
+ /// \brief Return the maximum width lock-free atomic operation which will
+ /// ever be supported for the given target
unsigned getMaxAtomicPromoteWidth() const { return MaxAtomicPromoteWidth; }
- /// getMaxAtomicInlineWidth - Return the maximum width lock-free atomic
- /// operation which can be inlined given the supported features of the
- /// given target.
+ /// \brief Return the maximum width lock-free atomic operation which can be
+ /// inlined given the supported features of the given target.
unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; }
- /// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this
- /// target, in bits.
+ /// \brief Return the size of intmax_t and uintmax_t for this target, in bits.
unsigned getIntMaxTWidth() const {
return getTypeWidth(IntMaxType);
}
- /// getRegisterWidth - Return the "preferred" register width on this target.
+ /// \brief Return the "preferred" register width on this target.
uint64_t getRegisterWidth() const {
// Currently we assume the register width on the target matches the pointer
// width, we can introduce a new variable for this if/when some target wants
@@ -314,22 +321,24 @@
return LongWidth;
}
- /// getUserLabelPrefix - This returns the default value of the
- /// __USER_LABEL_PREFIX__ macro, which is the prefix given to user symbols by
- /// default. On most platforms this is "_", but it is "" on some, and "." on
- /// others.
+ /// \brief Returns the default value of the __USER_LABEL_PREFIX__ macro,
+ /// which is the prefix given to user symbols by default.
+ ///
+ /// On most platforms this is "_", but it is "" on some, and "." on others.
const char *getUserLabelPrefix() const {
return UserLabelPrefix;
}
- /// MCountName - This returns name of the mcount instrumentation function.
+ /// \brief Returns the name of the mcount instrumentation function.
const char *getMCountName() const {
return MCountName;
}
- /// useSignedCharForObjCBool - Check if the Objective-C built-in boolean
- /// type should be signed char. Otherwise, if this returns false, the
- /// normal built-in boolean type should also be used for Objective-C.
+ /// \brief Check if the Objective-C built-in boolean type should be signed
+ /// char.
+ ///
+ /// Otherwise, if this returns false, the normal built-in boolean type
+ /// should also be used for Objective-C.
bool useSignedCharForObjCBool() const {
return UseSignedCharForObjCBool;
}
@@ -337,20 +346,20 @@
UseSignedCharForObjCBool = false;
}
- /// useBitFieldTypeAlignment() - Check whether the alignment of bit-field
- /// types is respected when laying out structures.
+ /// \brief Check whether the alignment of bit-field types is respected
+ /// when laying out structures.
bool useBitFieldTypeAlignment() const {
return UseBitFieldTypeAlignment;
}
- /// useZeroLengthBitfieldAlignment() - Check whether zero length bitfields
- /// should force alignment of the next member.
+ /// \brief Check whether zero length bitfields should force alignment of
+ /// the next member.
bool useZeroLengthBitfieldAlignment() const {
return UseZeroLengthBitfieldAlignment;
}
- /// getZeroLengthBitfieldBoundary() - Get the fixed alignment value in bits
- /// for a member that follows a zero length bitfield.
+ /// \brief Get the fixed alignment value in bits for a member that follows
+ /// a zero length bitfield.
unsigned getZeroLengthBitfieldBoundary() const {
return ZeroLengthBitfieldBoundary;
}
@@ -360,22 +369,24 @@
return HasAlignMac68kSupport;
}
- /// getTypeName - Return the user string for the specified integer type enum.
+ /// \brief Return the user string for the specified integer type enum.
+ ///
/// For example, SignedShort -> "short".
static const char *getTypeName(IntType T);
- /// getTypeConstantSuffix - Return the constant suffix for the specified
- /// integer type enum. For example, SignedLong -> "L".
+ /// \brief Return the constant suffix for the specified integer type enum.
+ ///
+ /// For example, SignedLong -> "L".
static const char *getTypeConstantSuffix(IntType T);
/// \brief Check whether the given real type should use the "fpret" flavor of
- /// Obj-C message passing on this target.
+ /// Objective-C message passing on this target.
bool useObjCFPRetForRealType(RealType T) const {
return RealTypeUsesObjCFPRet & (1 << T);
}
/// \brief Check whether _Complex long double should use the "fp2ret" flavor
- /// of Obj-C message passing on this target.
+ /// of Objective-C message passing on this target.
bool useObjCFP2RetForComplexLongDouble() const {
return ComplexLongDoubleUsesFP2Ret;
}
@@ -388,35 +399,38 @@
MacroBuilder &Builder) const = 0;
- /// getTargetBuiltins - Return information about target-specific builtins for
+ /// Return information about target-specific builtins for
/// the current primary target, and info about which builtins are non-portable
/// across the current set of primary and secondary targets.
virtual void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const = 0;
- /// isCLZForZeroUndef - The __builtin_clz* and __builtin_ctz* built-in
+ /// The __builtin_clz* and __builtin_ctz* built-in
/// functions are specified to have undefined results for zero inputs, but
/// on targets that support these operations in a way that provides
/// well-defined results for zero without loss of performance, it is a good
/// idea to avoid optimizing based on that undef behavior.
virtual bool isCLZForZeroUndef() const { return true; }
- /// getBuiltinVaListKind - Returns the kind of __builtin_va_list
- /// type that should be used with this target.
+ /// \brief Returns the kind of __builtin_va_list type that should be used
+ /// with this target.
virtual BuiltinVaListKind getBuiltinVaListKind() const = 0;
- /// isValidClobber - Returns whether the passed in string is
- /// a valid clobber in an inline asm statement. This is used by
- /// Sema.
+ /// \brief Returns whether the passed in string is a valid clobber in an
+ /// inline asm statement.
+ ///
+ /// This is used by Sema.
bool isValidClobber(StringRef Name) const;
- /// isValidGCCRegisterName - Returns whether the passed in string
- /// is a valid register name according to GCC. This is used by Sema for
- /// inline asm statements.
+ /// \brief Returns whether the passed in string is a valid register name
+ /// according to GCC.
+ ///
+ /// This is used by Sema for inline asm statements.
bool isValidGCCRegisterName(StringRef Name) const;
- // getNormalizedGCCRegisterName - Returns the "normalized" GCC register name.
- // For example, on x86 it will return "ax" when "eax" is passed in.
+ /// \brief Returns the "normalized" GCC register name.
+ ///
+ /// For example, on x86 it will return "ax" when "eax" is passed in.
StringRef getNormalizedGCCRegisterName(StringRef Name) const;
struct ConstraintInfo {
@@ -443,13 +457,15 @@
bool allowsRegister() const { return (Flags & CI_AllowsRegister) != 0; }
bool allowsMemory() const { return (Flags & CI_AllowsMemory) != 0; }
- /// hasMatchingInput - Return true if this output operand has a matching
+ /// \brief Return true if this output operand has a matching
/// (tied) input operand.
bool hasMatchingInput() const { return (Flags & CI_HasMatchingInput) != 0; }
- /// hasTiedOperand() - Return true if this input operand is a matching
- /// constraint that ties it to an output operand. If this returns true,
- /// then getTiedOperand will indicate which output operand this is tied to.
+ /// \brief Return true if this input operand is a matching
+ /// constraint that ties it to an output operand.
+ ///
+ /// If this returns true then getTiedOperand will indicate which output
+ /// operand this is tied to.
bool hasTiedOperand() const { return TiedOperand != -1; }
unsigned getTiedOperand() const {
assert(hasTiedOperand() && "Has no tied operand!");
@@ -461,9 +477,10 @@
void setAllowsRegister() { Flags |= CI_AllowsRegister; }
void setHasMatchingInput() { Flags |= CI_HasMatchingInput; }
- /// setTiedOperand - Indicate that this is an input operand that is tied to
- /// the specified output operand. Copy over the various constraint
- /// information from the output.
+ /// \brief Indicate that this is an input operand that is tied to
+ /// the specified output operand.
+ ///
+ /// Copy over the various constraint information from the output.
void setTiedOperand(unsigned N, ConstraintInfo &Output) {
Output.setHasMatchingInput();
Flags = Output.Flags;
@@ -493,11 +510,11 @@
return std::string(1, *Constraint);
}
- // Returns a string of target-specific clobbers, in LLVM format.
+ /// \brief Returns a string of target-specific clobbers, in LLVM format.
virtual const char *getClobbers() const = 0;
- /// getTriple - Return the target triple of the primary target.
+ /// \brief Returns the target triple of the primary target.
const llvm::Triple &getTriple() const {
return Triple;
}
@@ -516,8 +533,7 @@
const unsigned RegNum;
};
- /// hasProtectedVisibility - Does this target support "protected"
- /// visibility?
+ /// \brief Does this target support "protected" visibility?
///
/// Any target which dynamic libraries will naturally support
/// something like "default" (meaning that the symbol is visible
@@ -531,28 +547,29 @@
virtual bool useGlobalsForAutomaticVariables() const { return false; }
- /// getCFStringSection - Return the section to use for CFString
- /// literals, or 0 if no special section is used.
+ /// \brief Return the section to use for CFString literals, or 0 if no
+ /// special section is used.
virtual const char *getCFStringSection() const {
return "__DATA,__cfstring";
}
- /// getNSStringSection - Return the section to use for NSString
- /// literals, or 0 if no special section is used.
+ /// \brief Return the section to use for NSString literals, or 0 if no
+ /// special section is used.
virtual const char *getNSStringSection() const {
return "__OBJC,__cstring_object,regular,no_dead_strip";
}
- /// getNSStringNonFragileABISection - Return the section to use for
- /// NSString literals, or 0 if no special section is used (NonFragile ABI).
+ /// \brief Return the section to use for NSString literals, or 0 if no
+ /// special section is used (NonFragile ABI).
virtual const char *getNSStringNonFragileABISection() const {
return "__DATA, __objc_stringobj, regular, no_dead_strip";
}
- /// isValidSectionSpecifier - This is an optional hook that targets can
- /// implement to perform semantic checking on attribute((section("foo")))
- /// specifiers. In this case, "foo" is passed in to be checked. If the
- /// section specifier is invalid, the backend should return a non-empty string
+ /// \brief An optional hook that targets can implement to perform semantic
+ /// checking on attribute((section("foo"))) specifiers.
+ ///
+ /// In this case, "foo" is passed in to be checked. If the section
+ /// specifier is invalid, the backend should return a non-empty string
/// that indicates the problem.
///
/// This hook is a simple quality of implementation feature to catch errors
@@ -563,43 +580,44 @@
return "";
}
- /// setForcedLangOptions - Set forced language options.
+ /// \brief Set forced language options.
+ ///
/// Apply changes to the target information with respect to certain
/// language options which change the target configuration.
virtual void setForcedLangOptions(LangOptions &Opts);
- /// getDefaultFeatures - Get the default set of target features for the CPU;
+ /// \brief Get the default set of target features for the CPU;
/// this should include all legal feature strings on the target.
virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
}
- /// getABI - Get the ABI in use.
+ /// \brief Get the ABI currently in use.
virtual const char *getABI() const {
return "";
}
- /// getCXXABI - Get the C++ ABI in use.
+ /// \brief Get the C++ ABI currently in use.
virtual TargetCXXABI getCXXABI() const {
return CXXABI;
}
- /// setCPU - Target the specific CPU.
+ /// \brief Target the specified CPU.
///
- /// \return - False on error (invalid CPU name).
+ /// \return False on error (invalid CPU name).
virtual bool setCPU(const std::string &Name) {
return false;
}
- /// setABI - Use the specific ABI.
+ /// \brief Use the specified ABI.
///
- /// \return - False on error (invalid ABI name).
+ /// \return False on error (invalid ABI name).
virtual bool setABI(const std::string &Name) {
return false;
}
- /// setCXXABI - Use this specific C++ ABI.
+ /// \brief Use this specified C++ ABI.
///
- /// \return - False on error (invalid C++ ABI name).
+ /// \return False on error (invalid C++ ABI name).
bool setCXXABI(const std::string &Name) {
static const TargetCXXABI Unknown = static_cast<TargetCXXABI>(-1);
TargetCXXABI ABI = llvm::StringSwitch<TargetCXXABI>(Name)
@@ -611,27 +629,28 @@
return setCXXABI(ABI);
}
- /// setCXXABI - Set the C++ ABI to be used by this implementation.
+ /// \brief Set the C++ ABI to be used by this implementation.
///
- /// \return - False on error (ABI not valid on this target)
+ /// \return False on error (ABI not valid on this target)
virtual bool setCXXABI(TargetCXXABI ABI) {
CXXABI = ABI;
return true;
}
- /// setFeatureEnabled - Enable or disable a specific target feature,
+ /// \brief Enable or disable a specific target feature;
/// the feature name must be valid.
///
- /// \return - False on error (invalid feature name).
+ /// \return False on error (invalid feature name).
virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
StringRef Name,
bool Enabled) const {
return false;
}
- /// HandleTargetOptions - Perform initialization based on the user configured
- /// set of features (e.g., +sse4). The list is guaranteed to have at most one
- /// entry per feature.
+ /// \brief Perform initialization based on the user configured
+ /// set of features (e.g., +sse4).
+ ///
+ /// The list is guaranteed to have at most one entry per feature.
///
/// The target may modify the features list, to change which options are
/// passed onwards to the backend.
@@ -643,19 +662,20 @@
return false;
}
- // getRegParmMax - Returns maximal number of args passed in registers.
+ // \brief Returns maximal number of args passed in registers.
unsigned getRegParmMax() const {
assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle");
return RegParmMax;
}
- /// isTLSSupported - Whether the target supports thread-local storage.
+ /// \brief Whether the target supports thread-local storage.
bool isTLSSupported() const {
return TLSSupported;
}
- /// hasNoAsmVariants - Return true if {|} are normal characters in the
- /// asm string. If this returns false (the default), then {abc|xyz} is syntax
+ /// \brief Return true if {|} are normal characters in the asm string.
+ ///
+ /// If this returns false (the default), then {abc|xyz} is syntax
/// that says that when compiling for asm variant #0, "abc" should be
/// generated, but when compiling for asm variant #1, "xyz" should be
/// generated.
@@ -663,14 +683,13 @@
return NoAsmVariants;
}
- /// getEHDataRegisterNumber - Return the register number that
- /// __builtin_eh_return_regno would return with the specified argument.
+ /// \brief Return the register number that __builtin_eh_return_regno would
+ /// return with the specified argument.
virtual int getEHDataRegisterNumber(unsigned RegNo) const {
return -1;
}
- /// getStaticInitSectionSpecifier - Return the section to use for C++ static
- /// initialization functions.
+ /// \brief Return the section to use for C++ static initialization functions.
virtual const char *getStaticInitSectionSpecifier() const {
return 0;
}
Modified: cfe/branches/tooling/include/clang/Basic/TargetOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/TargetOptions.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/TargetOptions.h (original)
+++ cfe/branches/tooling/include/clang/Basic/TargetOptions.h Tue Jul 3 11:18:37 2012
@@ -6,6 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::TargetOptions class.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
#define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
@@ -15,7 +20,7 @@
namespace clang {
-/// TargetOptions - Options for controlling the target.
+/// \brief Options for controlling the target.
class TargetOptions {
public:
/// If given, the name of the target triple to compile for. If not given the
Modified: cfe/branches/tooling/include/clang/Basic/TemplateKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/TemplateKinds.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/TemplateKinds.h (original)
+++ cfe/branches/tooling/include/clang/Basic/TemplateKinds.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the TemplateNameKind enum.
-//
+///
+/// \file
+/// \brief Defines the clang::TemplateNameKind enum.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TEMPLATEKINDS_H
#define LLVM_CLANG_TEMPLATEKINDS_H
Modified: cfe/branches/tooling/include/clang/Basic/TokenKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/TokenKinds.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/TokenKinds.h (original)
+++ cfe/branches/tooling/include/clang/Basic/TokenKinds.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the TokenKind enum and support functions.
-//
+///
+/// \file
+/// \brief Defines the clang::TokenKind enum and support functions.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOKENKINDS_H
@@ -18,24 +19,23 @@
namespace tok {
-/// TokenKind - This provides a simple uniform namespace for tokens from all C
-/// languages.
+/// \brief Provides a simple uniform namespace for tokens from all C languages.
enum TokenKind {
#define TOK(X) X,
#include "clang/Basic/TokenKinds.def"
NUM_TOKENS
};
-/// PPKeywordKind - This provides a namespace for preprocessor keywords which
-/// start with a '#' at the beginning of the line.
+/// \brief Provides a namespace for preprocessor keywords which start with a
+/// '#' at the beginning of the line.
enum PPKeywordKind {
#define PPKEYWORD(X) pp_##X,
#include "clang/Basic/TokenKinds.def"
NUM_PP_KEYWORDS
};
-/// ObjCKeywordKind - This provides a namespace for Objective-C keywords which
-/// start with an '@'.
+/// \brief Provides a namespace for Objective-C keywords which start with
+/// an '@'.
enum ObjCKeywordKind {
#define OBJC1_AT_KEYWORD(X) objc_##X,
#define OBJC2_AT_KEYWORD(X) objc_##X,
@@ -43,8 +43,7 @@
NUM_OBJC_KEYWORDS
};
-/// OnOffSwitch - This defines the possible values of an on-off-switch
-/// (C99 6.10.6p2).
+/// \brief Defines the possible values of an on-off-switch (C99 6.10.6p2).
enum OnOffSwitch {
OOS_ON, OOS_OFF, OOS_DEFAULT
};
Modified: cfe/branches/tooling/include/clang/Basic/TypeTraits.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/TypeTraits.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/TypeTraits.h (original)
+++ cfe/branches/tooling/include/clang/Basic/TypeTraits.h Tue Jul 3 11:18:37 2012
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines enumerations for the type traits support.
-//
+///
+/// \file
+/// \brief Defines enumerations for the type traits support.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TYPETRAITS_H
@@ -16,7 +17,7 @@
namespace clang {
- /// UnaryTypeTrait - Names for the unary type traits.
+ /// \brief Names for the unary type traits.
enum UnaryTypeTrait {
UTT_HasNothrowAssign,
UTT_HasNothrowCopy,
@@ -62,7 +63,7 @@
UTT_IsVolatile
};
- /// BinaryTypeTrait - Names for the binary type traits.
+ /// \brief Names for the binary type traits.
enum BinaryTypeTrait {
BTT_IsBaseOf,
BTT_IsConvertible,
@@ -72,13 +73,13 @@
BTT_IsTriviallyAssignable
};
- /// ArrayTypeTrait - Names for the array type traits.
+ /// \brief Names for the array type traits.
enum ArrayTypeTrait {
ATT_ArrayRank,
ATT_ArrayExtent
};
- /// UnaryExprOrTypeTrait - Names for the "expression or type" traits.
+ /// \brief Names for the "expression or type" traits.
enum UnaryExprOrTypeTrait {
UETT_SizeOf,
UETT_AlignOf,
Modified: cfe/branches/tooling/include/clang/Basic/Version.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Version.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Version.h (original)
+++ cfe/branches/tooling/include/clang/Basic/Version.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This header defines version macros and version-related utility functions
-// for Clang.
-//
+///
+/// \file
+/// \brief Defines version macros and version-related utility functions
+/// for Clang.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_VERSION_H
@@ -26,8 +27,7 @@
/// \brief Helper macro for CLANG_VERSION_STRING.
#define CLANG_MAKE_VERSION_STRING(X,Y,Z) CLANG_MAKE_VERSION_STRING2(X.Y.Z)
-/// \brief A string that describes the Clang version number, e.g.,
-/// "1.0".
+/// \brief A string that describes the Clang version number, e.g., "1.0".
#define CLANG_VERSION_STRING \
CLANG_MAKE_VERSION_STRING(CLANG_VERSION_MAJOR,CLANG_VERSION_MINOR, \
CLANG_VERSION_PATCHLEVEL)
@@ -35,8 +35,7 @@
/// \brief Helper macro for CLANG_VERSION_STRING.
#define CLANG_MAKE_VERSION_STRING(X,Y) CLANG_MAKE_VERSION_STRING2(X.Y)
-/// \brief A string that describes the Clang version number, e.g.,
-/// "1.0".
+/// \brief A string that describes the Clang version number, e.g., "1.0".
#define CLANG_VERSION_STRING \
CLANG_MAKE_VERSION_STRING(CLANG_VERSION_MAJOR,CLANG_VERSION_MINOR)
#endif
@@ -47,31 +46,34 @@
/// Clang was built.
std::string getClangRepositoryPath();
- /// \brief Retrieves the repository path from which LLVM was built. Supports
- /// LLVM residing in a separate repository from clang.
+ /// \brief Retrieves the repository path from which LLVM was built.
+ ///
+ /// This supports LLVM residing in a separate repository from clang.
std::string getLLVMRepositoryPath();
/// \brief Retrieves the repository revision number (or identifer) from which
- /// this Clang was built.
+ /// this Clang was built.
std::string getClangRevision();
/// \brief Retrieves the repository revision number (or identifer) from which
- /// LLVM was built. If Clang and LLVM are in the same repository, this returns
- /// the same string as getClangRevision.
+ /// LLVM was built.
+ ///
+ /// If Clang and LLVM are in the same repository, this returns the same
+ /// string as getClangRevision.
std::string getLLVMRevision();
/// \brief Retrieves the full repository version that is an amalgamation of
- /// the information in getClangRepositoryPath() and getClangRevision().
+ /// the information in getClangRepositoryPath() and getClangRevision().
std::string getClangFullRepositoryVersion();
/// \brief Retrieves a string representing the complete clang version,
- /// which includes the clang version number, the repository version,
- /// and the vendor tag.
+ /// which includes the clang version number, the repository version,
+ /// and the vendor tag.
std::string getClangFullVersion();
/// \brief Retrieves a string representing the complete clang version suitable
- /// for use in the CPP __VERSION__ macro, which includes the clang version
- /// number, the repository version, and the vendor tag.
+ /// for use in the CPP __VERSION__ macro, which includes the clang version
+ /// number, the repository version, and the vendor tag.
std::string getClangFullCPPVersion();
}
Modified: cfe/branches/tooling/include/clang/Basic/VersionTuple.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/VersionTuple.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/VersionTuple.h (original)
+++ cfe/branches/tooling/include/clang/Basic/VersionTuple.h Tue Jul 3 11:18:37 2012
@@ -6,10 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This header defines the VersionTuple class, which represents a version in
-// the form major[.minor[.subminor]].
-//
+///
+/// \file
+/// \brief Defines the clang::VersionTuple class, which represents a version in
+/// the form major[.minor[.subminor]].
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_VERSIONTUPLE_H
#define LLVM_CLANG_BASIC_VERSIONTUPLE_H
@@ -73,15 +74,18 @@
return X.Major == Y.Major && X.Minor == Y.Minor && X.Subminor == Y.Subminor;
}
- /// \brief Determine if two version numbers are not equivalent. If
- /// not provided, minor and subminor version numbers are considered to be
+ /// \brief Determine if two version numbers are not equivalent.
+ ///
+ /// If not provided, minor and subminor version numbers are considered to be
/// zero.
friend bool operator!=(const VersionTuple &X, const VersionTuple &Y) {
return !(X == Y);
}
- /// \brief Determine whether one version number precedes another. If not
- /// provided, minor and subminor version numbers are considered to be zero.
+ /// \brief Determine whether one version number precedes another.
+ ///
+ /// If not provided, minor and subminor version numbers are considered to be
+ /// zero.
friend bool operator<(const VersionTuple &X, const VersionTuple &Y) {
if (X.Major != Y.Major)
return X.Major < Y.Major;
@@ -92,31 +96,37 @@
return X.Subminor < Y.Subminor;
}
- /// \brief Determine whether one version number follows another. If not
- /// provided, minor and subminor version numbers are considered to be zero.
+ /// \brief Determine whether one version number follows another.
+ ///
+ /// If not provided, minor and subminor version numbers are considered to be
+ /// zero.
friend bool operator>(const VersionTuple &X, const VersionTuple &Y) {
return Y < X;
}
/// \brief Determine whether one version number precedes or is
- /// equivalent to another. If not provided, minor and subminor
- /// version numbers are considered to be zero.
+ /// equivalent to another.
+ ///
+ /// If not provided, minor and subminor version numbers are considered to be
+ /// zero.
friend bool operator<=(const VersionTuple &X, const VersionTuple &Y) {
return !(Y < X);
}
/// \brief Determine whether one version number follows or is
- /// equivalent to another. If not provided, minor and subminor
- /// version numbers are considered to be zero.
+ /// equivalent to another.
+ ///
+ /// If not provided, minor and subminor version numbers are considered to be
+ /// zero.
friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) {
return !(X < Y);
}
- /// \brief Retrieve a string representation of the version number/
+ /// \brief Retrieve a string representation of the version number.
std::string getAsString() const;
/// \brief Try to parse the given string as a version number.
- /// Returns true if the string does not match the regular expression
+ /// \returns \c true if the string does not match the regular expression
/// [0-9]+(\.[0-9]+(\.[0-9]+))
bool tryParse(StringRef string);
};
Modified: cfe/branches/tooling/include/clang/Basic/Visibility.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Visibility.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Visibility.h (original)
+++ cfe/branches/tooling/include/clang/Basic/Visibility.h Tue Jul 3 11:18:37 2012
@@ -6,20 +6,23 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the Visibility enumeration and various utility
-// functions.
-//
+///
+/// \file
+/// \brief Defines the clang::Visibility enumeration and various utility
+/// functions.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_VISIBILITY_H
#define LLVM_CLANG_BASIC_VISIBILITY_H
namespace clang {
-/// Describes the different kinds of visibility that a
-/// declaration may have. Visibility determines how a declaration
-/// interacts with the dynamic linker. It may also affect whether the
-/// symbol can be found by runtime symbol lookup APIs.
+/// \brief Describes the different kinds of visibility that a declaration
+/// may have.
+///
+/// Visibility determines how a declaration interacts with the dynamic
+/// linker. It may also affect whether the symbol can be found by runtime
+/// symbol lookup APIs.
///
/// Visibility is not described in any language standard and
/// (nonetheless) sometimes has odd behavior. Not all platforms
Modified: cfe/branches/tooling/include/clang/Driver/Arg.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Driver/Arg.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Driver/Arg.h (original)
+++ cfe/branches/tooling/include/clang/Driver/Arg.h Tue Jul 3 11:18:37 2012
@@ -6,6 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::driver::Arg class for parsed arguments.
+///
+//===----------------------------------------------------------------------===//
#ifndef CLANG_DRIVER_ARG_H_
#define CLANG_DRIVER_ARG_H_
@@ -20,7 +25,7 @@
class ArgList;
class Option;
- /// Arg - A concrete instance of a particular driver option.
+ /// \brief A concrete instance of a particular driver option.
///
/// The Arg class encodes just enough information to be able to
/// derive the argument values efficiently. In addition, Arg
@@ -32,25 +37,26 @@
void operator=(const Arg &); // DO NOT IMPLEMENT
private:
- /// The option this argument is an instance of.
+ /// \brief The option this argument is an instance of.
const Option *Opt;
- /// The argument this argument was derived from (during tool chain
+ /// \brief The argument this argument was derived from (during tool chain
/// argument translation), if any.
const Arg *BaseArg;
- /// The index at which this argument appears in the containing
+ /// \brief The index at which this argument appears in the containing
/// ArgList.
unsigned Index;
- /// Was this argument used to effect compilation; used for generating
- /// "argument unused" diagnostics.
+ /// \brief Was this argument used to effect compilation?
+ ///
+ /// This is used for generating "argument unused" diagnostics.
mutable unsigned Claimed : 1;
- /// Does this argument own its values.
+ /// \brief Does this argument own its values?
mutable unsigned OwnsValues : 1;
- /// The argument values, as C strings.
+ /// \brief The argument values, as C strings.
SmallVector<const char *, 2> Values;
public:
@@ -64,8 +70,9 @@
const Option &getOption() const { return *Opt; }
unsigned getIndex() const { return Index; }
- /// getBaseArg - Return the base argument which generated this
- /// arg; this is either the argument itself or the argument it was
+ /// \brief Return the base argument which generated this arg.
+ ///
+ /// This is either the argument itself or the argument it was
/// derived from during tool chain specific argument translation.
const Arg &getBaseArg() const {
return BaseArg ? *BaseArg : *this;
@@ -79,7 +86,7 @@
bool isClaimed() const { return getBaseArg().Claimed; }
- /// claim - Set the Arg claimed bit.
+ /// \brief Set the Arg claimed bit.
void claim() const { getBaseArg().Claimed = true; }
unsigned getNumValues() const { return Values.size(); }
@@ -98,20 +105,21 @@
return false;
}
- /// render - Append the argument onto the given array as strings.
+ /// \brief Append the argument onto the given array as strings.
void render(const ArgList &Args, ArgStringList &Output) const;
- /// renderAsInput - Append the argument, render as an input, onto
- /// the given array as strings. The distinction is that some
- /// options only render their values when rendered as a input
- /// (e.g., Xlinker).
+ /// \brief Append the argument, render as an input, onto the given
+ /// array as strings.
+ ///
+ /// The distinction is that some options only render their values
+ /// when rendered as a input (e.g., Xlinker).
void renderAsInput(const ArgList &Args, ArgStringList &Output) const;
static bool classof(const Arg *) { return true; }
void dump() const;
- /// getAsString - Return a formatted version of the argument and
+ /// \brief Return a formatted version of the argument and
/// its values, for debugging and diagnostics.
std::string getAsString(const ArgList &Args) const;
};
Modified: cfe/branches/tooling/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Driver/CC1Options.td?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Driver/CC1Options.td (original)
+++ cfe/branches/tooling/include/clang/Driver/CC1Options.td Tue Jul 3 11:18:37 2012
@@ -269,6 +269,8 @@
HelpText<"Include code patterns in code-completion results">;
def no_code_completion_globals : Flag<"-no-code-completion-globals">,
HelpText<"Do not include global declarations in code-completion results.">;
+def code_completion_brief_comments : Flag<"-code-completion-brief-comments">,
+ HelpText<"Include brief documentation comments in code-completion results.">;
def disable_free : Flag<"-disable-free">,
HelpText<"Disable freeing of memory on exit">;
def load : Separate<"-load">, MetaVarName<"<dsopath>">,
Modified: cfe/branches/tooling/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/ASTUnit.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/ASTUnit.h Tue Jul 3 11:18:37 2012
@@ -248,7 +248,11 @@
std::vector<serialization::DeclID> TopLevelDeclsInPreamble;
/// \brief Whether we should be caching code-completion results.
- bool ShouldCacheCodeCompletionResults;
+ bool ShouldCacheCodeCompletionResults : 1;
+
+ /// \brief Whether to include brief documentation within the set of code
+ /// completions cached.
+ bool IncludeBriefCommentsInCodeCompletion : 1;
/// \brief The language options used when we load an AST file.
LangOptions ASTFileLangOpts;
@@ -681,6 +685,7 @@
bool CaptureDiagnostics = false,
bool PrecompilePreamble = false,
bool CacheCodeCompletionResults = false,
+ bool IncludeBriefCommentsInCodeCompletion = false,
OwningPtr<ASTUnit> *ErrAST = 0);
/// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
@@ -700,7 +705,8 @@
bool CaptureDiagnostics = false,
bool PrecompilePreamble = false,
TranslationUnitKind TUKind = TU_Complete,
- bool CacheCodeCompletionResults = false);
+ bool CacheCodeCompletionResults = false,
+ bool IncludeBriefCommentsInCodeCompletion = false);
/// LoadFromCommandLine - Create an ASTUnit from a vector of command line
/// arguments, which must specify exactly one source file.
@@ -732,6 +738,7 @@
bool PrecompilePreamble = false,
TranslationUnitKind TUKind = TU_Complete,
bool CacheCodeCompletionResults = false,
+ bool IncludeBriefCommentsInCodeCompletion = false,
bool AllowPCHWithCompilerErrors = false,
bool SkipFunctionBodies = false,
OwningPtr<ASTUnit> *ErrAST = 0);
@@ -759,11 +766,15 @@
/// \param IncludeCodePatterns Whether to include code patterns (such as a
/// for loop) in the code-completion results.
///
+ /// \param IncludeBriefComments Whether to include brief documentation within
+ /// the set of code completions returned.
+ ///
/// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and
/// OwnedBuffers parameters are all disgusting hacks. They will go away.
void CodeComplete(StringRef File, unsigned Line, unsigned Column,
RemappedFile *RemappedFiles, unsigned NumRemappedFiles,
bool IncludeMacros, bool IncludeCodePatterns,
+ bool IncludeBriefComments,
CodeCompleteConsumer &Consumer,
DiagnosticsEngine &Diag, LangOptions &LangOpts,
SourceManager &SourceMgr, FileManager &FileMgr,
Modified: cfe/branches/tooling/include/clang/Frontend/CompilerInstance.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/CompilerInstance.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/CompilerInstance.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/CompilerInstance.h Tue Jul 3 11:18:37 2012
@@ -560,8 +560,7 @@
static CodeCompleteConsumer *
createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
unsigned Line, unsigned Column,
- bool ShowMacros,
- bool ShowCodePatterns, bool ShowGlobals,
+ const CodeCompleteOptions &Opts,
raw_ostream &OS);
/// \brief Create the Sema object to be used for parsing.
Modified: cfe/branches/tooling/include/clang/Frontend/FrontendOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/FrontendOptions.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/FrontendOptions.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/FrontendOptions.h Tue Jul 3 11:18:37 2012
@@ -11,6 +11,7 @@
#define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
#include "clang/Frontend/CommandLineSourceLoc.h"
+#include "clang/Sema/CodeCompleteOptions.h"
#include "llvm/ADT/StringRef.h"
#include <string>
#include <vector>
@@ -84,7 +85,7 @@
FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false)
: File(File.str()), Kind(Kind), IsSystem(IsSystem) { }
};
-
+
/// FrontendOptions - Options for controlling the behavior of the frontend.
class FrontendOptions {
public:
@@ -93,12 +94,6 @@
/// instruct the AST writer to create
/// relocatable PCH files.
unsigned ShowHelp : 1; ///< Show the -help text.
- unsigned ShowMacrosInCodeCompletion : 1; ///< Show macros in code completion
- /// results.
- unsigned ShowCodePatternsInCodeCompletion : 1; ///< Show code patterns in code
- /// completion results.
- unsigned ShowGlobalSymbolsInCodeCompletion : 1; ///< Show top-level decls in
- /// code completion results.
unsigned ShowStats : 1; ///< Show frontend performance
/// metrics and statistics.
unsigned ShowTimers : 1; ///< Show timers for individual
@@ -116,6 +111,8 @@
/// not need them (e.g. with code
/// completion).
+ CodeCompleteOptions CodeCompleteOpts;
+
enum {
ARCMT_None,
ARCMT_Check,
@@ -183,9 +180,6 @@
ActionName = "";
RelocatablePCH = 0;
ShowHelp = 0;
- ShowMacrosInCodeCompletion = 0;
- ShowCodePatternsInCodeCompletion = 0;
- ShowGlobalSymbolsInCodeCompletion = 1;
ShowStats = 0;
ShowTimers = 0;
ShowVersion = 0;
Modified: cfe/branches/tooling/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Parse/Parser.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Parse/Parser.h (original)
+++ cfe/branches/tooling/include/clang/Parse/Parser.h Tue Jul 3 11:18:37 2012
@@ -1019,7 +1019,7 @@
void ParseLexedMethodDef(LexedMethod &LM);
void ParseLexedMemberInitializers(ParsingClass &Class);
void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI);
- Decl *ParseLexedObjCMethodDefs(LexedMethod &LM);
+ void ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod);
bool ConsumeAndStoreFunctionPrologue(CachedTokens &Toks);
bool ConsumeAndStoreUntil(tok::TokenKind T1,
CachedTokens &Toks,
@@ -1084,11 +1084,12 @@
struct ObjCImplParsingDataRAII {
Parser &P;
Decl *Dcl;
+ bool HasCFunction;
typedef SmallVector<LexedMethod*, 8> LateParsedObjCMethodContainer;
LateParsedObjCMethodContainer LateParsedObjCMethods;
ObjCImplParsingDataRAII(Parser &parser, Decl *D)
- : P(parser), Dcl(D) {
+ : P(parser), Dcl(D), HasCFunction(false) {
P.CurParsedObjCImpl = this;
Finished = false;
}
@@ -1101,6 +1102,7 @@
bool Finished;
};
ObjCImplParsingDataRAII *CurParsedObjCImpl;
+ void StashAwayMethodOrFunctionBodyTokens(Decl *MDecl);
DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc);
DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
@@ -1949,7 +1951,7 @@
//===--------------------------------------------------------------------===//
// C++ 9: classes [class] and C structs/unions.
- bool isValidAfterTypeSpecifier();
+ bool isValidAfterTypeSpecifier(bool CouldBeBitfield);
void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo,
AccessSpecifier AS, bool EnteringContext,
Modified: cfe/branches/tooling/include/clang/Sema/CodeCompleteConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/CodeCompleteConsumer.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/CodeCompleteConsumer.h (original)
+++ cfe/branches/tooling/include/clang/Sema/CodeCompleteConsumer.h Tue Jul 3 11:18:37 2012
@@ -15,6 +15,7 @@
#include "clang/AST/Type.h"
#include "clang/AST/CanonicalType.h"
+#include "clang/Sema/CodeCompleteOptions.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
@@ -444,6 +445,10 @@
/// \brief The name of the parent context.
StringRef ParentName;
+
+ /// \brief A brief documentation comment attached to the declaration of
+ /// entity being completed by this result.
+ const char *BriefComment;
CodeCompletionString(const CodeCompletionString &); // DO NOT IMPLEMENT
CodeCompletionString &operator=(const CodeCompletionString &); // DITTO
@@ -451,7 +456,8 @@
CodeCompletionString(const Chunk *Chunks, unsigned NumChunks,
unsigned Priority, CXAvailabilityKind Availability,
const char **Annotations, unsigned NumAnnotations,
- CXCursorKind ParentKind, StringRef ParentName);
+ CXCursorKind ParentKind, StringRef ParentName,
+ const char *BriefComment);
~CodeCompletionString() { }
friend class CodeCompletionBuilder;
@@ -493,6 +499,10 @@
StringRef getParentContextName() const {
return ParentName;
}
+
+ const char *getBriefComment() const {
+ return BriefComment;
+ }
/// \brief Retrieve a string representation of the code completion string,
/// which is mainly useful for debugging.
@@ -569,6 +579,7 @@
CXAvailabilityKind Availability;
CXCursorKind ParentKind;
StringRef ParentName;
+ const char *BriefComment;
/// \brief The chunks stored in this string.
SmallVector<Chunk, 4> Chunks;
@@ -580,14 +591,14 @@
CodeCompletionTUInfo &CCTUInfo)
: Allocator(Allocator), CCTUInfo(CCTUInfo),
Priority(0), Availability(CXAvailability_Available),
- ParentKind(CXCursor_NotImplemented) { }
+ ParentKind(CXCursor_NotImplemented), BriefComment(NULL) { }
CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
CodeCompletionTUInfo &CCTUInfo,
unsigned Priority, CXAvailabilityKind Availability)
: Allocator(Allocator), CCTUInfo(CCTUInfo),
Priority(Priority), Availability(Availability),
- ParentKind(CXCursor_NotImplemented) { }
+ ParentKind(CXCursor_NotImplemented), BriefComment(NULL) { }
/// \brief Retrieve the allocator into which the code completion
/// strings should be allocated.
@@ -628,6 +639,8 @@
/// \brief Add the parent context information to this code completion.
void addParentContext(DeclContext *DC);
+
+ void addBriefComment(StringRef Comment);
CXCursorKind getParentKind() const { return ParentKind; }
StringRef getParentName() const { return ParentName; }
@@ -780,11 +793,13 @@
/// string itself.
CodeCompletionString *CreateCodeCompletionString(Sema &S,
CodeCompletionAllocator &Allocator,
- CodeCompletionTUInfo &CCTUInfo);
+ CodeCompletionTUInfo &CCTUInfo,
+ bool IncludeBriefComments);
CodeCompletionString *CreateCodeCompletionString(ASTContext &Ctx,
Preprocessor &PP,
CodeCompletionAllocator &Allocator,
- CodeCompletionTUInfo &CCTUInfo);
+ CodeCompletionTUInfo &CCTUInfo,
+ bool IncludeBriefComments);
/// \brief Determine a base priority for the given declaration.
static unsigned getPriorityFromDecl(NamedDecl *ND);
@@ -818,16 +833,7 @@
/// information.
class CodeCompleteConsumer {
protected:
- /// \brief Whether to include macros in the code-completion results.
- bool IncludeMacros;
-
- /// \brief Whether to include code patterns (such as for loops) within
- /// the completion results.
- bool IncludeCodePatterns;
-
- /// \brief Whether to include global (top-level) declarations and names in
- /// the completion results.
- bool IncludeGlobals;
+ const CodeCompleteOptions CodeCompleteOpts;
/// \brief Whether the output format for the code-completion consumer is
/// binary.
@@ -900,22 +906,31 @@
CodeCompletionTUInfo &CCTUInfo) const;
};
- CodeCompleteConsumer() : IncludeMacros(false), IncludeCodePatterns(false),
- IncludeGlobals(true), OutputIsBinary(false) { }
-
- CodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
- bool IncludeGlobals, bool OutputIsBinary)
- : IncludeMacros(IncludeMacros), IncludeCodePatterns(IncludeCodePatterns),
- IncludeGlobals(IncludeGlobals), OutputIsBinary(OutputIsBinary) { }
+ CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
+ bool OutputIsBinary)
+ : CodeCompleteOpts(CodeCompleteOpts), OutputIsBinary(OutputIsBinary)
+ { }
/// \brief Whether the code-completion consumer wants to see macros.
- bool includeMacros() const { return IncludeMacros; }
+ bool includeMacros() const {
+ return CodeCompleteOpts.IncludeMacros;
+ }
/// \brief Whether the code-completion consumer wants to see code patterns.
- bool includeCodePatterns() const { return IncludeCodePatterns; }
+ bool includeCodePatterns() const {
+ return CodeCompleteOpts.IncludeCodePatterns;
+ }
/// \brief Whether to include global (top-level) declaration results.
- bool includeGlobals() const { return IncludeGlobals; }
+ bool includeGlobals() const {
+ return CodeCompleteOpts.IncludeGlobals;
+ }
+
+ /// \brief Whether to include brief documentation comments within the set of
+ /// code completions returned.
+ bool includeBriefComments() const {
+ return CodeCompleteOpts.IncludeBriefComments;
+ }
/// \brief Determine whether the output of this consumer is binary.
bool isOutputBinary() const { return OutputIsBinary; }
@@ -962,11 +977,9 @@
public:
/// \brief Create a new printing code-completion consumer that prints its
/// results to the given raw output stream.
- PrintingCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
- bool IncludeGlobals,
+ PrintingCodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
raw_ostream &OS)
- : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals,
- false), OS(OS),
+ : CodeCompleteConsumer(CodeCompleteOpts, false), OS(OS),
CCTUInfo(new GlobalCodeCompletionAllocator) {}
/// \brief Prints the finalized code-completion results.
Modified: cfe/branches/tooling/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/ScopeInfo.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/branches/tooling/include/clang/Sema/ScopeInfo.h Tue Jul 3 11:18:37 2012
@@ -93,7 +93,7 @@
/// \brief The list of return statements that occur within the function or
/// block, if there is any chance of applying the named return value
- /// optimization.
+ /// optimization, or if we need to infer a return type.
SmallVector<ReturnStmt*, 4> Returns;
/// \brief The stack of currently active compound stamement scopes in the
Modified: cfe/branches/tooling/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/Sema.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/Sema.h (original)
+++ cfe/branches/tooling/include/clang/Sema/Sema.h Tue Jul 3 11:18:37 2012
@@ -168,6 +168,7 @@
namespace sema {
class AccessedEntity;
class BlockScopeInfo;
+ class CapturingScopeInfo;
class CompoundScopeInfo;
class DelayedDiagnostic;
class DelayedDiagnosticPool;
@@ -1316,7 +1317,11 @@
void CheckForFunctionRedefinition(FunctionDecl *FD);
Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D);
- void ActOnStartOfObjCMethodDef(Scope *S, Decl *D);
+ void ActOnStartOfObjCMethodOrCFunctionDef(Scope *S, Decl *D,
+ bool parseMethod);
+ bool isObjCMethodDecl(Decl *D) {
+ return D && isa<ObjCMethodDecl>(D);
+ }
void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope);
Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body);
@@ -4016,6 +4021,10 @@
/// \brief Introduce the lambda parameters into scope.
void addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope);
+
+ /// \brief Deduce a block or lambda's return type based on the return
+ /// statements present in the body.
+ void deduceClosureReturnType(sema::CapturingScopeInfo &CSI);
/// ActOnStartOfLambdaDefinition - This is called just before we start
/// parsing the body of a lambda; it analyzes the explicit captures and
Modified: cfe/branches/tooling/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Serialization/ASTWriter.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/branches/tooling/include/clang/Serialization/ASTWriter.h Tue Jul 3 11:18:37 2012
@@ -110,6 +110,10 @@
/// serialization, rather than just queueing updates.
bool WritingAST;
+ /// \brief Indicates that we are done serializing the collection of decls
+ /// and types to emit.
+ bool DoneWritingDeclsAndTypes;
+
/// \brief Indicates that the AST contained compiler errors.
bool ASTHasCompilerErrors;
@@ -296,6 +300,10 @@
/// it.
llvm::SmallPtrSet<const DeclContext *, 16> UpdatedDeclContexts;
+ /// \brief Keeps track of visible decls that were added in DeclContexts
+ /// coming from another AST file.
+ SmallVector<const Decl *, 16> UpdatingVisibleDecls;
+
typedef llvm::SmallPtrSet<const Decl *, 16> DeclsToRewriteTy;
/// \brief Decls that will be replaced in the current dependent AST file.
DeclsToRewriteTy DeclsToRewrite;
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/Checker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/Checker.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/Checker.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/Checker.h Tue Jul 3 11:18:37 2012
@@ -122,7 +122,7 @@
class PreObjCMessage {
template <typename CHECKER>
- static void _checkObjCMessage(void *checker, const ObjCMessage &msg,
+ static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
CheckerContext &C) {
((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
}
@@ -137,7 +137,7 @@
class PostObjCMessage {
template <typename CHECKER>
- static void _checkObjCMessage(void *checker, const ObjCMessage &msg,
+ static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
CheckerContext &C) {
((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
}
@@ -150,6 +150,36 @@
}
};
+class PreCall {
+ template <typename CHECKER>
+ static void _checkCall(void *checker, const CallEvent &msg,
+ CheckerContext &C) {
+ ((const CHECKER *)checker)->checkPreCall(msg, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForPreCall(
+ CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
+ }
+};
+
+class PostCall {
+ template <typename CHECKER>
+ static void _checkCall(void *checker, const CallEvent &msg,
+ CheckerContext &C) {
+ ((const CHECKER *)checker)->checkPostCall(msg, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForPostCall(
+ CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
+ }
+};
+
class Location {
template <typename CHECKER>
static void _checkLocation(void *checker,
@@ -266,7 +296,7 @@
const StoreManager::InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> Explicits,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call) {
+ const CallEvent *Call) {
return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
Explicits, Regions, Call);
}
@@ -372,16 +402,14 @@
typename CHECK11=check::_VoidCheck,typename CHECK12=check::_VoidCheck,
typename CHECK13=check::_VoidCheck,typename CHECK14=check::_VoidCheck,
typename CHECK15=check::_VoidCheck,typename CHECK16=check::_VoidCheck,
- typename CHECK17=check::_VoidCheck,typename CHECK18=check::_VoidCheck>
+ typename CHECK17=check::_VoidCheck,typename CHECK18=check::_VoidCheck,
+ typename CHECK19=check::_VoidCheck,typename CHECK20=check::_VoidCheck,
+ typename CHECK21=check::_VoidCheck,typename CHECK22=check::_VoidCheck,
+ typename CHECK23=check::_VoidCheck,typename CHECK24=check::_VoidCheck>
class Checker;
template <>
-class Checker<check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
- check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
- check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
- check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
- check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
- check::_VoidCheck, check::_VoidCheck, check::_VoidCheck>
+class Checker<check::_VoidCheck>
: public CheckerBase
{
virtual void anchor();
@@ -393,19 +421,22 @@
typename CHECK5, typename CHECK6, typename CHECK7, typename CHECK8,
typename CHECK9, typename CHECK10,typename CHECK11,typename CHECK12,
typename CHECK13,typename CHECK14,typename CHECK15,typename CHECK16,
- typename CHECK17,typename CHECK18>
+ typename CHECK17,typename CHECK18,typename CHECK19,typename CHECK20,
+ typename CHECK21,typename CHECK22,typename CHECK23,typename CHECK24>
class Checker
: public CHECK1,
- public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8,
- CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,CHECK14,CHECK15,
- CHECK16,CHECK17,CHECK18> {
+ public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7,
+ CHECK8, CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,
+ CHECK14,CHECK15,CHECK16,CHECK17,CHECK18,CHECK19,
+ CHECK20,CHECK21,CHECK22,CHECK23,CHECK24> {
public:
template <typename CHECKER>
static void _register(CHECKER *checker, CheckerManager &mgr) {
CHECK1::_register(checker, mgr);
- Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8,
- CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,CHECK14,CHECK15,
- CHECK16,CHECK17,CHECK18>::_register(checker, mgr);
+ Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7,
+ CHECK8, CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,
+ CHECK14,CHECK15,CHECK16,CHECK17,CHECK18,CHECK19,
+ CHECK20,CHECK21,CHECK22,CHECK23,CHECK24>::_register(checker, mgr);
}
};
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h Tue Jul 3 11:18:37 2012
@@ -33,7 +33,8 @@
class AnalysisManager;
class BugReporter;
class CheckerContext;
- class ObjCMessage;
+ class SimpleCall;
+ class ObjCMethodCall;
class SVal;
class ExplodedNode;
class ExplodedNodeSet;
@@ -44,12 +45,6 @@
class MemRegion;
class SymbolReaper;
-class GraphExpander {
-public:
- virtual ~GraphExpander();
- virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) = 0;
-};
-
template <typename T> class CheckerFn;
template <typename RET, typename P1, typename P2, typename P3, typename P4,
@@ -207,7 +202,7 @@
/// \brief Run checkers for pre-visiting obj-c messages.
void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
- const ObjCMessage &msg,
+ const ObjCMethodCall &msg,
ExprEngine &Eng) {
runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
}
@@ -215,7 +210,7 @@
/// \brief Run checkers for post-visiting obj-c messages.
void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
- const ObjCMessage &msg,
+ const ObjCMethodCall &msg,
ExprEngine &Eng) {
runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng);
}
@@ -224,7 +219,24 @@
void runCheckersForObjCMessage(bool isPreVisit,
ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
- const ObjCMessage &msg, ExprEngine &Eng);
+ const ObjCMethodCall &msg, ExprEngine &Eng);
+
+ /// \brief Run checkers for pre-visiting obj-c messages.
+ void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
+ const CallEvent &Call, ExprEngine &Eng) {
+ runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
+ }
+
+ /// \brief Run checkers for post-visiting obj-c messages.
+ void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
+ const CallEvent &Call, ExprEngine &Eng) {
+ runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng);
+ }
+
+ /// \brief Run checkers for visiting obj-c messages.
+ void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
+ const ExplodedNodeSet &Src,
+ const CallEvent &Call, ExprEngine &Eng);
/// \brief Run checkers for load/store of a location.
void runCheckersForLocation(ExplodedNodeSet &Dst,
@@ -294,7 +306,7 @@
const StoreManager::InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call);
+ const CallEvent *Call);
/// \brief Run checkers for handling assumptions on symbolic values.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
@@ -303,8 +315,7 @@
/// \brief Run checkers for evaluating a call.
void runCheckersForEvalCall(ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
- const CallExpr *CE, ExprEngine &Eng,
- GraphExpander *defaultEval = 0);
+ const SimpleCall &CE, ExprEngine &Eng);
/// \brief Run checkers for the entire Translation Unit.
void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
@@ -343,8 +354,11 @@
typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
- typedef CheckerFn<void (const ObjCMessage &, CheckerContext &)>
+ typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
CheckObjCMessageFunc;
+
+ typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
+ CheckCallFunc;
typedef CheckerFn<void (const SVal &location, bool isLoad,
const Stmt *S,
@@ -373,7 +387,7 @@
const StoreManager::InvalidatedSymbols *symbols,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call)>
+ const CallEvent *Call)>
CheckRegionChangesFunc;
typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
@@ -403,6 +417,9 @@
void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
+ void _registerForPreCall(CheckCallFunc checkfn);
+ void _registerForPostCall(CheckCallFunc checkfn);
+
void _registerForLocation(CheckLocationFunc checkfn);
void _registerForBind(CheckBindFunc checkfn);
@@ -524,6 +541,9 @@
std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
+ std::vector<CheckCallFunc> PreCallCheckers;
+ std::vector<CheckCallFunc> PostCallCheckers;
+
std::vector<CheckLocationFunc> LocationCheckers;
std::vector<CheckBindFunc> BindCheckers;
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Tue Jul 3 11:18:37 2012
@@ -41,8 +41,9 @@
namespace ento {
class AnalysisManager;
-class CallOrObjCMessage;
-class ObjCMessage;
+class CallEvent;
+class SimpleCall;
+class ObjCMethodCall;
class ExprEngine : public SubEngine {
AnalysisManager &AMgr;
@@ -240,7 +241,7 @@
const StoreManager::InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call);
+ const CallEvent *Call);
/// printState - Called by ProgramStateManager to print checker-specific data.
void printState(raw_ostream &Out, ProgramStateRef State,
@@ -347,7 +348,7 @@
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
ExplodedNode *Pred, ExplodedNodeSet &Dst);
- void VisitObjCMessage(const ObjCMessage &msg, ExplodedNode *Pred,
+ void VisitObjCMessage(const ObjCMethodCall &Msg, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
/// VisitReturnStmt - Transfer function logic for return statements.
@@ -433,14 +434,10 @@
}
protected:
- void evalObjCMessage(StmtNodeBuilder &Bldr, const ObjCMessage &msg,
+ void evalObjCMessage(StmtNodeBuilder &Bldr, const ObjCMethodCall &Msg,
ExplodedNode *Pred, ProgramStateRef state,
bool GenSink);
- ProgramStateRef invalidateArguments(ProgramStateRef State,
- const CallOrObjCMessage &Call,
- const LocationContext *LC);
-
ProgramStateRef MarkBranch(ProgramStateRef state,
const Stmt *Terminator,
const LocationContext *LCtx,
@@ -472,6 +469,11 @@
void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE,
ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val,
const ProgramPointTag *tag = 0);
+
+ void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
+ const SimpleCall &Call);
+ void defaultEvalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
+ const CallEvent &Call);
private:
void evalLoadCommon(ExplodedNodeSet &Dst,
const Expr *NodeEx, /* Eventually will be a CFGStmt */
@@ -492,7 +494,8 @@
const ProgramPointTag *tag, bool isLoad);
bool shouldInlineDecl(const Decl *D, ExplodedNode *Pred);
- bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred);
+ bool inlineCall(ExplodedNodeSet &Dst, const CallEvent &Call,
+ ExplodedNode *Pred);
bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC);
};
Removed: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h?rev=159662&view=auto
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h (removed)
@@ -1,300 +0,0 @@
-//===- ObjCMessage.h - Wrapper for ObjC messages and dot syntax ---*- 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 ObjCMessage which serves as a common wrapper for ObjC
-// message expressions or implicit messages for loading/storing ObjC properties.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_OBJCMESSAGE
-#define LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_OBJCMESSAGE
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-namespace ento {
-using llvm::StrInStrNoCase;
-
-/// \brief Represents both explicit ObjC message expressions and implicit
-/// messages that are sent for handling properties in dot syntax.
-class ObjCMessage {
- const ObjCMessageExpr *Msg;
- const ObjCPropertyRefExpr *PE;
- const bool IsPropSetter;
-public:
- ObjCMessage() : Msg(0), PE(0), IsPropSetter(false) {}
-
- ObjCMessage(const ObjCMessageExpr *E, const ObjCPropertyRefExpr *pe = 0,
- bool isSetter = false)
- : Msg(E), PE(pe), IsPropSetter(isSetter) {
- assert(E && "should not be initialized with null expression");
- }
-
- bool isValid() const { return Msg; }
-
- bool isPureMessageExpr() const { return !PE; }
-
- bool isPropertyGetter() const { return PE && !IsPropSetter; }
-
- bool isPropertySetter() const {
- return IsPropSetter;
- }
-
- const Expr *getMessageExpr() const {
- return Msg;
- }
-
- QualType getType(ASTContext &ctx) const {
- return Msg->getType();
- }
-
- QualType getResultType(ASTContext &ctx) const {
- if (const ObjCMethodDecl *MD = Msg->getMethodDecl())
- return MD->getResultType();
- return getType(ctx);
- }
-
- ObjCMethodFamily getMethodFamily() const {
- return Msg->getMethodFamily();
- }
-
- Selector getSelector() const {
- return Msg->getSelector();
- }
-
- const Expr *getInstanceReceiver() const {
- return Msg->getInstanceReceiver();
- }
-
- SVal getInstanceReceiverSVal(ProgramStateRef State,
- const LocationContext *LC) const {
- if (!isInstanceMessage())
- return UndefinedVal();
- if (const Expr *Ex = getInstanceReceiver())
- return State->getSValAsScalarOrLoc(Ex, LC);
-
- // An instance message with no expression means we are sending to super.
- // In this case the object reference is the same as 'self'.
- const ImplicitParamDecl *SelfDecl = LC->getSelfDecl();
- assert(SelfDecl && "No message receiver Expr, but not in an ObjC method");
- return State->getSVal(State->getRegion(SelfDecl, LC));
- }
-
- bool isInstanceMessage() const {
- return Msg->isInstanceMessage();
- }
-
- const ObjCMethodDecl *getMethodDecl() const {
- return Msg->getMethodDecl();
- }
-
- const ObjCInterfaceDecl *getReceiverInterface() const {
- return Msg->getReceiverInterface();
- }
-
- SourceLocation getSuperLoc() const {
- if (PE)
- return PE->getReceiverLocation();
- return Msg->getSuperLoc();
- }
-
- SourceRange getSourceRange() const LLVM_READONLY {
- if (PE)
- return PE->getSourceRange();
- return Msg->getSourceRange();
- }
-
- unsigned getNumArgs() const {
- return Msg->getNumArgs();
- }
-
- SVal getArgSVal(unsigned i,
- const LocationContext *LCtx,
- ProgramStateRef state) const {
- assert(i < getNumArgs() && "Invalid index for argument");
- return state->getSVal(Msg->getArg(i), LCtx);
- }
-
- QualType getArgType(unsigned i) const {
- assert(i < getNumArgs() && "Invalid index for argument");
- return Msg->getArg(i)->getType();
- }
-
- const Expr *getArgExpr(unsigned i) const {
- assert(i < getNumArgs() && "Invalid index for argument");
- return Msg->getArg(i);
- }
-
- SourceRange getArgSourceRange(unsigned i) const {
- const Expr *argE = getArgExpr(i);
- return argE->getSourceRange();
- }
-
- SourceRange getReceiverSourceRange() const {
- if (PE) {
- if (PE->isObjectReceiver())
- return PE->getBase()->getSourceRange();
- }
- else {
- return Msg->getReceiverRange();
- }
-
- // FIXME: This isn't a range.
- return PE->getReceiverLocation();
- }
-};
-
-/// \brief Common wrapper for a call expression, ObjC message, or C++
-/// constructor, mainly to provide a common interface for their arguments.
-class CallOrObjCMessage {
- llvm::PointerUnion<const CallExpr *, const CXXConstructExpr *> CallE;
- ObjCMessage Msg;
- ProgramStateRef State;
- const LocationContext *LCtx;
-
- bool isCallbackArg(unsigned Idx, const Type *T) const;
-
-public:
- CallOrObjCMessage(const CallExpr *callE, ProgramStateRef state,
- const LocationContext *lctx)
- : CallE(callE), State(state), LCtx(lctx) {}
- CallOrObjCMessage(const CXXConstructExpr *consE, ProgramStateRef state,
- const LocationContext *lctx)
- : CallE(consE), State(state), LCtx(lctx) {}
- CallOrObjCMessage(const ObjCMessage &msg, ProgramStateRef state,
- const LocationContext *lctx)
- : CallE((CallExpr *)0), Msg(msg), State(state), LCtx(lctx) {}
-
- QualType getResultType(ASTContext &ctx) const;
-
- bool isFunctionCall() const {
- return CallE && CallE.is<const CallExpr *>();
- }
-
- bool isCXXConstructExpr() const {
- return CallE && CallE.is<const CXXConstructExpr *>();
- }
-
- bool isObjCMessage() const {
- return !CallE;
- }
-
- bool isCXXCall() const {
- const CallExpr *ActualCallE = CallE.dyn_cast<const CallExpr *>();
- return ActualCallE && isa<CXXMemberCallExpr>(ActualCallE);
- }
-
- /// Check if the callee is declared in the system header.
- bool isInSystemHeader() const {
- if (const Decl *D = getDecl()) {
- const SourceManager &SM =
- State->getStateManager().getContext().getSourceManager();
- SourceLocation Loc = D->getLocation();
- // Be careful: the implicit declarations of operator new/delete have
- // invalid source locations but should still count as system files.
- if (Loc.isValid())
- return SM.isInSystemHeader(D->getLocation());
- else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
- return FD->isOverloadedOperator() && FD->isImplicit() && FD->isGlobal();
- }
- return false;
- }
-
- const Expr *getOriginExpr() const {
- if (!CallE)
- return Msg.getMessageExpr();
- if (const CXXConstructExpr *Ctor =
- CallE.dyn_cast<const CXXConstructExpr *>())
- return Ctor;
- return CallE.get<const CallExpr *>();
- }
-
- SVal getFunctionCallee() const;
- SVal getCXXCallee() const;
- SVal getInstanceMessageReceiver(const LocationContext *LC) const;
-
- /// Get the declaration of the function or method.
- const Decl *getDecl() const;
-
- unsigned getNumArgs() const {
- if (!CallE)
- return Msg.getNumArgs();
- if (const CXXConstructExpr *Ctor =
- CallE.dyn_cast<const CXXConstructExpr *>())
- return Ctor->getNumArgs();
- return CallE.get<const CallExpr *>()->getNumArgs();
- }
-
- SVal getArgSVal(unsigned i) const {
- assert(i < getNumArgs());
- if (!CallE)
- return Msg.getArgSVal(i, LCtx, State);
- return State->getSVal(getArg(i), LCtx);
- }
-
- const Expr *getArg(unsigned i) const {
- assert(i < getNumArgs());
- if (!CallE)
- return Msg.getArgExpr(i);
- if (const CXXConstructExpr *Ctor =
- CallE.dyn_cast<const CXXConstructExpr *>())
- return Ctor->getArg(i);
- return CallE.get<const CallExpr *>()->getArg(i);
- }
-
- SourceRange getArgSourceRange(unsigned i) const {
- assert(i < getNumArgs());
- if (CallE)
- return getArg(i)->getSourceRange();
- return Msg.getArgSourceRange(i);
- }
-
- SourceRange getReceiverSourceRange() const {
- assert(isObjCMessage());
- return Msg.getReceiverSourceRange();
- }
-
- /// \brief Check if one of the arguments might be a callback.
- bool hasNonZeroCallbackArg() const;
-
-
- /// \brief Check if the name corresponds to a CoreFoundation or CoreGraphics
- /// function that allows objects to escape.
- ///
- /// Many methods allow a tracked object to escape. For example:
- ///
- /// CFMutableDictionaryRef x = CFDictionaryCreateMutable(..., customDeallocator);
- /// CFDictionaryAddValue(y, key, x);
- ///
- /// We handle this and similar cases with the following heuristic. If the
- /// function name contains "InsertValue", "SetValue", "AddValue",
- /// "AppendValue", or "SetAttribute", then we assume that arguments may
- /// escape.
- //
- // TODO: To reduce false negatives here, we should track the container
- // allocation site and check if a proper deallocator was set there.
- static bool isCFCGAllowingEscape(StringRef FName);
-
- // Check if this kind of expression can be inlined by the analyzer.
- static bool canBeInlined(const Stmt *S) {
- return isa<CallExpr>(S);
- }
-};
-
-}
-}
-
-#endif
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h Tue Jul 3 11:18:37 2012
@@ -35,7 +35,7 @@
namespace ento {
-class CallOrObjCMessage;
+class CallEvent;
typedef ConstraintManager* (*ConstraintManagerCreator)(ProgramStateManager&,
SubEngine&);
@@ -219,7 +219,7 @@
const Expr *E, unsigned BlockCount,
const LocationContext *LCtx,
StoreManager::InvalidatedSymbols *IS = 0,
- const CallOrObjCMessage *Call = 0) const;
+ const CallEvent *Call = 0) const;
/// enterStackFrame - Returns the state for entry to the given stack frame,
/// preserving the current state.
@@ -381,7 +381,7 @@
const Expr *E, unsigned BlockCount,
const LocationContext *LCtx,
StoreManager::InvalidatedSymbols &IS,
- const CallOrObjCMessage *Call) const;
+ const CallEvent *Call) const;
};
//===----------------------------------------------------------------------===//
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h Tue Jul 3 11:18:37 2012
@@ -29,7 +29,7 @@
namespace ento {
-class CallOrObjCMessage;
+class CallEvent;
class ProgramState;
class ProgramStateManager;
class SubRegionMap;
@@ -194,7 +194,7 @@
const Expr *E, unsigned Count,
const LocationContext *LCtx,
InvalidatedSymbols &IS,
- const CallOrObjCMessage *Call,
+ const CallEvent *Call,
InvalidatedRegions *Invalidated) = 0;
/// enterStackFrame - Let the StoreManager to do something when execution
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h Tue Jul 3 11:18:37 2012
@@ -105,7 +105,7 @@
const StoreManager::InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call) = 0;
+ const CallEvent *Call) = 0;
inline ProgramStateRef
Modified: cfe/branches/tooling/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/Decl.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/Decl.cpp (original)
+++ cfe/branches/tooling/lib/AST/Decl.cpp Tue Jul 3 11:18:37 2012
@@ -2524,6 +2524,12 @@
return DeclaratorDecl::getSourceRange();
}
+void FieldDecl::setBitWidth(Expr *Width) {
+ assert(!InitializerOrBitWidth.getPointer() && !hasInClassInitializer() &&
+ "bit width or initializer already set");
+ InitializerOrBitWidth.setPointer(Width);
+}
+
void FieldDecl::setInClassInitializer(Expr *Init) {
assert(!InitializerOrBitWidth.getPointer() && hasInClassInitializer() &&
"bit width or initializer already set");
Modified: cfe/branches/tooling/lib/AST/RawCommentList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/RawCommentList.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/RawCommentList.cpp (original)
+++ cfe/branches/tooling/lib/AST/RawCommentList.cpp Tue Jul 3 11:18:37 2012
@@ -130,7 +130,7 @@
return StringRef(BufferStart + BeginOffset, Length);
}
-StringRef RawComment::extractBriefText(const ASTContext &Context) const {
+const char *RawComment::extractBriefText(const ASTContext &Context) const {
// Make sure that RawText is valid.
getRawText(Context.getSourceManager());
@@ -142,10 +142,10 @@
const unsigned BriefTextLength = Result.size();
char *BriefTextPtr = new (Context) char[BriefTextLength + 1];
memcpy(BriefTextPtr, Result.c_str(), BriefTextLength + 1);
- BriefText = StringRef(BriefTextPtr, BriefTextLength);
+ BriefText = BriefTextPtr;
BriefTextValid = true;
- return BriefText;
+ return BriefTextPtr;
}
namespace {
Modified: cfe/branches/tooling/lib/Analysis/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/LiveVariables.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/LiveVariables.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/LiveVariables.cpp Tue Jul 3 11:18:37 2012
@@ -486,6 +486,11 @@
if (!cfg)
return 0;
+ // The analysis currently has scalability issues for very large CFGs.
+ // Bail out if it looks too large.
+ if (cfg->getNumBlockIDs() > 300000)
+ return 0;
+
LiveVariablesImpl *LV = new LiveVariablesImpl(AC, killAtAssign);
// Construct the dataflow worklist. Enqueue the exit block as the
Modified: cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp Tue Jul 3 11:18:37 2012
@@ -924,9 +924,9 @@
ThreadSafetyAnalyzer(ThreadSafetyHandler &H) : Handler(H) {}
Lockset addLock(const Lockset &LSet, const MutexID &Mutex,
- const LockData &LDat);
+ const LockData &LDat, bool Warn=true);
Lockset addLock(const Lockset &LSet, Expr *MutexExp, const NamedDecl *D,
- const LockData &LDat);
+ const LockData &LDat, bool Warn=true);
Lockset removeLock(const Lockset &LSet, const MutexID &Mutex,
SourceLocation UnlockLoc,
bool Warn=true, bool FullyRemove=false);
@@ -951,7 +951,13 @@
const CFGBlock *CurrBlock);
Lockset intersectAndWarn(const Lockset &LSet1, const Lockset &LSet2,
- SourceLocation JoinLoc, LockErrorKind LEK);
+ SourceLocation JoinLoc,
+ LockErrorKind LEK1, LockErrorKind LEK2);
+
+ Lockset intersectAndWarn(const Lockset &LSet1, const Lockset &LSet2,
+ SourceLocation JoinLoc, LockErrorKind LEK1) {
+ return intersectAndWarn(LSet1, LSet2, JoinLoc, LEK1, LEK1);
+ }
void runAnalysis(AnalysisDeclContext &AC);
};
@@ -962,11 +968,13 @@
/// \param LDat -- the LockData for the lock
Lockset ThreadSafetyAnalyzer::addLock(const Lockset &LSet,
const MutexID &Mutex,
- const LockData &LDat) {
+ const LockData &LDat,
+ bool Warn) {
// FIXME: deal with acquired before/after annotations.
// FIXME: Don't always warn when we have support for reentrant locks.
if (LSet.lookup(Mutex)) {
- Handler.handleDoubleLock(Mutex.getName(), LDat.AcquireLoc);
+ if (Warn)
+ Handler.handleDoubleLock(Mutex.getName(), LDat.AcquireLoc);
return LSet;
} else {
return LocksetFactory.add(LSet, Mutex, LDat);
@@ -976,13 +984,14 @@
/// \brief Construct a new mutex and add it to the lockset.
Lockset ThreadSafetyAnalyzer::addLock(const Lockset &LSet,
Expr *MutexExp, const NamedDecl *D,
- const LockData &LDat) {
+ const LockData &LDat,
+ bool Warn) {
MutexID Mutex(MutexExp, 0, D);
if (!Mutex.isValid()) {
MutexID::warnInvalidLock(Handler, MutexExp, 0, D);
return LSet;
}
- return addLock(LSet, Mutex, LDat);
+ return addLock(LSet, Mutex, LDat, Warn);
}
@@ -1538,42 +1547,63 @@
/// \param LSet1 The first lockset.
/// \param LSet2 The second lockset.
/// \param JoinLoc The location of the join point for error reporting
-/// \param LEK The error message to report.
+/// \param LEK1 The error message to report if a mutex is missing from LSet1
+/// \param LEK2 The error message to report if a mutex is missing from Lset2
Lockset ThreadSafetyAnalyzer::intersectAndWarn(const Lockset &LSet1,
const Lockset &LSet2,
SourceLocation JoinLoc,
- LockErrorKind LEK) {
+ LockErrorKind LEK1,
+ LockErrorKind LEK2) {
Lockset Intersection = LSet1;
for (Lockset::iterator I = LSet2.begin(), E = LSet2.end(); I != E; ++I) {
const MutexID &LSet2Mutex = I.getKey();
- const LockData &LSet2LockData = I.getData();
- if (const LockData *LD = LSet1.lookup(LSet2Mutex)) {
- if (LD->LKind != LSet2LockData.LKind) {
+ const LockData &LDat2 = I.getData();
+ if (const LockData *LDat1 = LSet1.lookup(LSet2Mutex)) {
+ if (LDat1->LKind != LDat2.LKind) {
Handler.handleExclusiveAndShared(LSet2Mutex.getName(),
- LSet2LockData.AcquireLoc,
- LD->AcquireLoc);
- if (LD->LKind != LK_Exclusive)
- Intersection = LocksetFactory.add(Intersection, LSet2Mutex,
- LSet2LockData);
+ LDat2.AcquireLoc,
+ LDat1->AcquireLoc);
+ if (LDat1->LKind != LK_Exclusive)
+ Intersection = LocksetFactory.add(Intersection, LSet2Mutex, LDat2);
}
} else {
- if (!LSet2LockData.Managed)
+ if (LDat2.UnderlyingMutex.isValid()) {
+ if (LSet2.lookup(LDat2.UnderlyingMutex)) {
+ // If this is a scoped lock that manages another mutex, and if the
+ // underlying mutex is still held, then warn about the underlying
+ // mutex.
+ Handler.handleMutexHeldEndOfScope(LDat2.UnderlyingMutex.getName(),
+ LDat2.AcquireLoc,
+ JoinLoc, LEK1);
+ }
+ }
+ else if (!LDat2.Managed)
Handler.handleMutexHeldEndOfScope(LSet2Mutex.getName(),
- LSet2LockData.AcquireLoc,
- JoinLoc, LEK);
+ LDat2.AcquireLoc,
+ JoinLoc, LEK1);
}
}
for (Lockset::iterator I = LSet1.begin(), E = LSet1.end(); I != E; ++I) {
if (!LSet2.contains(I.getKey())) {
const MutexID &Mutex = I.getKey();
- const LockData &MissingLock = I.getData();
+ const LockData &LDat1 = I.getData();
- if (!MissingLock.Managed)
+ if (LDat1.UnderlyingMutex.isValid()) {
+ if (LSet1.lookup(LDat1.UnderlyingMutex)) {
+ // If this is a scoped lock that manages another mutex, and if the
+ // underlying mutex is still held, then warn about the underlying
+ // mutex.
+ Handler.handleMutexHeldEndOfScope(LDat1.UnderlyingMutex.getName(),
+ LDat1.AcquireLoc,
+ JoinLoc, LEK1);
+ }
+ }
+ else if (!LDat1.Managed)
Handler.handleMutexHeldEndOfScope(Mutex.getName(),
- MissingLock.AcquireLoc,
- JoinLoc, LEK);
+ LDat1.AcquireLoc,
+ JoinLoc, LEK2);
Intersection = LocksetFactory.remove(Intersection, Mutex);
}
}
@@ -1637,14 +1667,14 @@
SLRIter = SLRAttr->args_begin(),
SLREnd = SLRAttr->args_end(); SLRIter != SLREnd; ++SLRIter)
InitialLockset = addLock(InitialLockset, *SLRIter, D,
- LockData(AttrLoc, LK_Shared));
+ LockData(AttrLoc, LK_Shared), false);
} else if (ExclusiveLocksRequiredAttr *ELRAttr
= dyn_cast<ExclusiveLocksRequiredAttr>(Attr)) {
for (ExclusiveLocksRequiredAttr::args_iterator
ELRIter = ELRAttr->args_begin(),
ELREnd = ELRAttr->args_end(); ELRIter != ELREnd; ++ELRIter)
InitialLockset = addLock(InitialLockset, *ELRIter, D,
- LockData(AttrLoc, LK_Exclusive));
+ LockData(AttrLoc, LK_Exclusive), false);
} else if (isa<UnlockFunctionAttr>(Attr)) {
// Don't try to check unlock functions for now
return;
@@ -1654,6 +1684,12 @@
} else if (isa<SharedLockFunctionAttr>(Attr)) {
// Don't try to check lock functions for now
return;
+ } else if (isa<ExclusiveTrylockFunctionAttr>(Attr)) {
+ // Don't try to check trylock functions for now
+ return;
+ } else if (isa<SharedTrylockFunctionAttr>(Attr)) {
+ // Don't try to check trylock functions for now
+ return;
}
}
}
@@ -1809,7 +1845,8 @@
// FIXME: Should we call this function for all blocks which exit the function?
intersectAndWarn(Initial->EntrySet, Final->ExitSet,
Final->ExitLoc,
- LEK_LockedAtEndOfFunction);
+ LEK_LockedAtEndOfFunction,
+ LEK_NotLockedAtEndOfFunction);
}
} // end anonymous namespace
Modified: cfe/branches/tooling/lib/Analysis/UninitializedValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/UninitializedValues.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/UninitializedValues.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/UninitializedValues.cpp Tue Jul 3 11:18:37 2012
@@ -116,6 +116,7 @@
BVPair &getValueVectors(const CFGBlock *block, bool shouldLazyCreate);
+ void setAllScratchValues(Value V);
void mergeIntoScratch(ValueVector const &source, bool isFirst);
bool updateValueVectorWithScratch(const CFGBlock *block);
bool updateValueVectors(const CFGBlock *block, const BVPair &newVals);
@@ -240,6 +241,11 @@
}
#endif
+void CFGBlockValues::setAllScratchValues(Value V) {
+ for (unsigned I = 0, E = scratch.size(); I != E; ++I)
+ scratch[I] = V;
+}
+
void CFGBlockValues::mergeIntoScratch(ValueVector const &source,
bool isFirst) {
if (isFirst)
@@ -374,6 +380,7 @@
void reportUse(const Expr *ex, const VarDecl *vd);
void VisitBlockExpr(BlockExpr *be);
+ void VisitCallExpr(CallExpr *ce);
void VisitDeclStmt(DeclStmt *ds);
void VisitDeclRefExpr(DeclRefExpr *dr);
void VisitUnaryOperator(UnaryOperator *uo);
@@ -576,6 +583,17 @@
}
}
+void TransferFunctions::VisitCallExpr(CallExpr *ce) {
+ // After a call to a function like setjmp or vfork, any variable which is
+ // initialized anywhere within this function may now be initialized. For now,
+ // just assume such a call initializes all variables.
+ // FIXME: Only mark variables as initialized if they have an initializer which
+ // is reachable from here.
+ Decl *Callee = ce->getCalleeDecl();
+ if (Callee && Callee->hasAttr<ReturnsTwiceAttr>())
+ vals.setAllScratchValues(Initialized);
+}
+
void TransferFunctions::VisitDeclRefExpr(DeclRefExpr *dr) {
// Record the last DeclRefExpr seen. This is an lvalue computation.
// We use this value to later detect if a variable "escapes" the analysis.
Modified: cfe/branches/tooling/lib/Basic/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/CMakeLists.txt?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/CMakeLists.txt (original)
+++ cfe/branches/tooling/lib/Basic/CMakeLists.txt Tue Jul 3 11:18:37 2012
@@ -3,6 +3,7 @@
add_clang_library(clangBasic
Builtins.cpp
ConvertUTF.c
+ ConvertUTFWrapper.cpp
Diagnostic.cpp
DiagnosticIDs.cpp
FileManager.cpp
Modified: cfe/branches/tooling/lib/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/SourceManager.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/SourceManager.cpp (original)
+++ cfe/branches/tooling/lib/Basic/SourceManager.cpp Tue Jul 3 11:18:37 2012
@@ -1854,8 +1854,6 @@
return LOffs.first < ROffs.first;
}
-/// PrintStats - Print statistics to stderr.
-///
void SourceManager::PrintStats() const {
llvm::errs() << "\n*** Source Manager Stats:\n";
llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
Modified: cfe/branches/tooling/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExpr.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExpr.cpp Tue Jul 3 11:18:37 2012
@@ -109,15 +109,18 @@
/// can have any type. The result is returned as an RValue struct.
/// If this is an aggregate expression, AggSlot indicates where the
/// result should be returned.
-RValue CodeGenFunction::EmitAnyExpr(const Expr *E, AggValueSlot AggSlot,
- bool IgnoreResult) {
+RValue CodeGenFunction::EmitAnyExpr(const Expr *E,
+ AggValueSlot aggSlot,
+ bool ignoreResult) {
if (!hasAggregateLLVMType(E->getType()))
- return RValue::get(EmitScalarExpr(E, IgnoreResult));
+ return RValue::get(EmitScalarExpr(E, ignoreResult));
else if (E->getType()->isAnyComplexType())
- return RValue::getComplex(EmitComplexExpr(E, IgnoreResult, IgnoreResult));
+ return RValue::getComplex(EmitComplexExpr(E, ignoreResult, ignoreResult));
- EmitAggExpr(E, AggSlot, IgnoreResult);
- return AggSlot.asRValue();
+ if (!ignoreResult && aggSlot.isIgnored())
+ aggSlot = CreateAggTemp(E->getType(), "agg-temp");
+ EmitAggExpr(E, aggSlot);
+ return aggSlot.asRValue();
}
/// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result will
@@ -1729,47 +1732,13 @@
return GV;
}
-// FIXME: Mostly copied from StringLiteralParser::CopyStringFragment
static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source,
SmallString<32>& Target) {
Target.resize(CharByteWidth * (Source.size() + 1));
char* ResultPtr = &Target[0];
-
- assert(CharByteWidth==1 || CharByteWidth==2 || CharByteWidth==4);
- ConversionResult result = conversionOK;
- // Copy the character span over.
- if (CharByteWidth == 1) {
- if (!isLegalUTF8String(reinterpret_cast<const UTF8*>(&*Source.begin()),
- reinterpret_cast<const UTF8*>(&*Source.end())))
- result = sourceIllegal;
- memcpy(ResultPtr, Source.data(), Source.size());
- ResultPtr += Source.size();
- } else if (CharByteWidth == 2) {
- UTF8 const *sourceStart = (UTF8 const *)Source.data();
- // FIXME: Make the type of the result buffer correct instead of
- // using reinterpret_cast.
- UTF16 *targetStart = reinterpret_cast<UTF16*>(ResultPtr);
- ConversionFlags flags = strictConversion;
- result = ConvertUTF8toUTF16(
- &sourceStart,sourceStart + Source.size(),
- &targetStart,targetStart + 2*Source.size(),flags);
- if (result==conversionOK)
- ResultPtr = reinterpret_cast<char*>(targetStart);
- } else if (CharByteWidth == 4) {
- UTF8 const *sourceStart = (UTF8 const *)Source.data();
- // FIXME: Make the type of the result buffer correct instead of
- // using reinterpret_cast.
- UTF32 *targetStart = reinterpret_cast<UTF32*>(ResultPtr);
- ConversionFlags flags = strictConversion;
- result = ConvertUTF8toUTF32(
- &sourceStart,sourceStart + Source.size(),
- &targetStart,targetStart + 4*Source.size(),flags);
- if (result==conversionOK)
- ResultPtr = reinterpret_cast<char*>(targetStart);
- }
- assert((result != targetExhausted)
- && "ConvertUTF8toUTFXX exhausted target buffer");
- assert(result == conversionOK);
+ bool success = ConvertUTF8toWide(CharByteWidth, Source, ResultPtr);
+ (void)success;
+ assert(success);
Target.resize(ResultPtr - &Target[0]);
}
Modified: cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp Tue Jul 3 11:18:37 2012
@@ -34,7 +34,6 @@
CodeGenFunction &CGF;
CGBuilderTy &Builder;
AggValueSlot Dest;
- bool IgnoreResult;
/// We want to use 'dest' as the return slot except under two
/// conditions:
@@ -56,12 +55,14 @@
if (!Dest.isIgnored()) return Dest;
return CGF.CreateAggTemp(T, "agg.tmp.ensured");
}
+ void EnsureDest(QualType T) {
+ if (!Dest.isIgnored()) return;
+ Dest = CGF.CreateAggTemp(T, "agg.tmp.ensured");
+ }
public:
- AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest,
- bool ignore)
- : CGF(cgf), Builder(CGF.Builder), Dest(Dest),
- IgnoreResult(ignore) {
+ AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest)
+ : CGF(cgf), Builder(CGF.Builder), Dest(Dest) {
}
//===--------------------------------------------------------------------===//
@@ -74,9 +75,11 @@
void EmitAggLoadOfLValue(const Expr *E);
/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
- void EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore = false);
- void EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore = false,
- unsigned Alignment = 0);
+ void EmitFinalDestCopy(QualType type, const LValue &src);
+ void EmitFinalDestCopy(QualType type, RValue src,
+ CharUnits srcAlignment = CharUnits::Zero());
+ void EmitCopy(QualType type, const AggValueSlot &dest,
+ const AggValueSlot &src);
void EmitMoveFromReturnSlot(const Expr *E, RValue Src);
@@ -119,7 +122,7 @@
if (E->getDecl()->getType()->isReferenceType()) {
if (CodeGenFunction::ConstantEmission result
= CGF.tryEmitAsConstant(E)) {
- EmitFinalDestCopy(E, result.getReferenceLValue(CGF, E));
+ EmitFinalDestCopy(E->getType(), result.getReferenceLValue(CGF, E));
return;
}
}
@@ -171,7 +174,7 @@
void VisitPseudoObjectExpr(PseudoObjectExpr *E) {
if (E->isGLValue()) {
LValue LV = CGF.EmitPseudoObjectLValue(E);
- return EmitFinalDestCopy(E, LV);
+ return EmitFinalDestCopy(E->getType(), LV);
}
CGF.EmitPseudoObjectRValue(E, EnsureSlot(E->getType()));
@@ -198,7 +201,7 @@
/// then loads the result into DestPtr.
void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
LValue LV = CGF.EmitLValue(E);
- EmitFinalDestCopy(E, LV);
+ EmitFinalDestCopy(E->getType(), LV);
}
/// \brief True if the given aggregate type requires special GC API calls.
@@ -228,7 +231,7 @@
/// If nothing interferes, this will cause the result to be emitted
/// directly into the return value slot. Otherwise, a final move
/// will be performed.
-void AggExprEmitter::EmitMoveFromReturnSlot(const Expr *E, RValue Src) {
+void AggExprEmitter::EmitMoveFromReturnSlot(const Expr *E, RValue src) {
if (shouldUseDestForReturnSlot()) {
// Logically, Dest.getAddr() should equal Src.getAggregateAddr().
// The possibility of undef rvalues complicates that a lot,
@@ -236,61 +239,58 @@
return;
}
- // Otherwise, do a final copy,
- assert(Dest.getAddr() != Src.getAggregateAddr());
- std::pair<CharUnits, CharUnits> TypeInfo =
+ // Otherwise, copy from there to the destination.
+ assert(Dest.getAddr() != src.getAggregateAddr());
+ std::pair<CharUnits, CharUnits> typeInfo =
CGF.getContext().getTypeInfoInChars(E->getType());
- CharUnits Alignment = std::min(TypeInfo.second, Dest.getAlignment());
- EmitFinalDestCopy(E, Src, /*Ignore*/ true, Alignment.getQuantity());
+ EmitFinalDestCopy(E->getType(), src, typeInfo.second);
}
/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
-void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore,
- unsigned Alignment) {
- assert(Src.isAggregate() && "value must be aggregate value!");
+void AggExprEmitter::EmitFinalDestCopy(QualType type, RValue src,
+ CharUnits srcAlign) {
+ assert(src.isAggregate() && "value must be aggregate value!");
+ LValue srcLV = CGF.MakeAddrLValue(src.getAggregateAddr(), type, srcAlign);
+ EmitFinalDestCopy(type, srcLV);
+}
+/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
+void AggExprEmitter::EmitFinalDestCopy(QualType type, const LValue &src) {
// If Dest is ignored, then we're evaluating an aggregate expression
- // in a context (like an expression statement) that doesn't care
- // about the result. C says that an lvalue-to-rvalue conversion is
- // performed in these cases; C++ says that it is not. In either
- // case, we don't actually need to do anything unless the value is
- // volatile.
- if (Dest.isIgnored()) {
- if (!Src.isVolatileQualified() ||
- CGF.CGM.getLangOpts().CPlusPlus ||
- (IgnoreResult && Ignore))
- return;
+ // in a context that doesn't care about the result. Note that loads
+ // from volatile l-values force the existence of a non-ignored
+ // destination.
+ if (Dest.isIgnored())
+ return;
- // If the source is volatile, we must read from it; to do that, we need
- // some place to put it.
- Dest = CGF.CreateAggTemp(E->getType(), "agg.tmp");
- }
+ AggValueSlot srcAgg =
+ AggValueSlot::forLValue(src, AggValueSlot::IsDestructed,
+ needsGC(type), AggValueSlot::IsAliased);
+ EmitCopy(type, Dest, srcAgg);
+}
- if (Dest.requiresGCollection()) {
- CharUnits size = CGF.getContext().getTypeSizeInChars(E->getType());
- llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
- llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size.getQuantity());
+/// Perform a copy from the source into the destination.
+///
+/// \param type - the type of the aggregate being copied; qualifiers are
+/// ignored
+void AggExprEmitter::EmitCopy(QualType type, const AggValueSlot &dest,
+ const AggValueSlot &src) {
+ if (dest.requiresGCollection()) {
+ CharUnits sz = CGF.getContext().getTypeSizeInChars(type);
+ llvm::Value *size = llvm::ConstantInt::get(CGF.SizeTy, sz.getQuantity());
CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF,
- Dest.getAddr(),
- Src.getAggregateAddr(),
- SizeVal);
+ dest.getAddr(),
+ src.getAddr(),
+ size);
return;
}
- // If the result of the assignment is used, copy the LHS there also.
- // FIXME: Pass VolatileDest as well. I think we also need to merge volatile
- // from the source as well, as we can't eliminate it if either operand
- // is volatile, unless copy has volatile for both source and destination..
- CGF.EmitAggregateCopy(Dest.getAddr(), Src.getAggregateAddr(), E->getType(),
- Dest.isVolatile()|Src.isVolatileQualified(),
- Alignment);
-}
-/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
-void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) {
- assert(Src.isSimple() && "Can't have aggregate bitfield, vector, etc");
-
- CharUnits Alignment = std::min(Src.getAlignment(), Dest.getAlignment());
- EmitFinalDestCopy(E, Src.asAggregateRValue(), Ignore, Alignment.getQuantity());
+ // If the result of the assignment is used, copy the LHS there also.
+ // It's volatile if either side is. Use the minimum alignment of
+ // the two sides.
+ CGF.EmitAggregateCopy(dest.getAddr(), src.getAddr(), type,
+ dest.isVolatile() || src.isVolatile(),
+ std::min(dest.getAlignment(), src.getAlignment()));
}
static QualType GetStdInitializerListElementType(QualType T) {
@@ -526,7 +526,7 @@
}
void AggExprEmitter::VisitOpaqueValueExpr(OpaqueValueExpr *e) {
- EmitFinalDestCopy(e, CGF.getOpaqueLValueMapping(e));
+ EmitFinalDestCopy(e->getType(), CGF.getOpaqueLValueMapping(e));
}
void
@@ -582,7 +582,15 @@
"should have been unpacked before we got here");
}
- case CK_LValueToRValue: // hope for downstream optimization
+ case CK_LValueToRValue:
+ // If we're loading from a volatile type, force the destination
+ // into existence.
+ if (E->getSubExpr()->getType().isVolatileQualified()) {
+ EnsureDest(E->getType());
+ return Visit(E->getSubExpr());
+ }
+ // fallthrough
+
case CK_NoOp:
case CK_AtomicToNonAtomic:
case CK_NonAtomicToAtomic:
@@ -676,7 +684,73 @@
void AggExprEmitter::VisitPointerToDataMemberBinaryOperator(
const BinaryOperator *E) {
LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E);
- EmitFinalDestCopy(E, LV);
+ EmitFinalDestCopy(E->getType(), LV);
+}
+
+/// Is the value of the given expression possibly a reference to or
+/// into a __block variable?
+static bool isBlockVarRef(const Expr *E) {
+ // Make sure we look through parens.
+ E = E->IgnoreParens();
+
+ // Check for a direct reference to a __block variable.
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+ const VarDecl *var = dyn_cast<VarDecl>(DRE->getDecl());
+ return (var && var->hasAttr<BlocksAttr>());
+ }
+
+ // More complicated stuff.
+
+ // Binary operators.
+ if (const BinaryOperator *op = dyn_cast<BinaryOperator>(E)) {
+ // For an assignment or pointer-to-member operation, just care
+ // about the LHS.
+ if (op->isAssignmentOp() || op->isPtrMemOp())
+ return isBlockVarRef(op->getLHS());
+
+ // For a comma, just care about the RHS.
+ if (op->getOpcode() == BO_Comma)
+ return isBlockVarRef(op->getRHS());
+
+ // FIXME: pointer arithmetic?
+ return false;
+
+ // Check both sides of a conditional operator.
+ } else if (const AbstractConditionalOperator *op
+ = dyn_cast<AbstractConditionalOperator>(E)) {
+ return isBlockVarRef(op->getTrueExpr())
+ || isBlockVarRef(op->getFalseExpr());
+
+ // OVEs are required to support BinaryConditionalOperators.
+ } else if (const OpaqueValueExpr *op
+ = dyn_cast<OpaqueValueExpr>(E)) {
+ if (const Expr *src = op->getSourceExpr())
+ return isBlockVarRef(src);
+
+ // Casts are necessary to get things like (*(int*)&var) = foo().
+ // We don't really care about the kind of cast here, except
+ // we don't want to look through l2r casts, because it's okay
+ // to get the *value* in a __block variable.
+ } else if (const CastExpr *cast = dyn_cast<CastExpr>(E)) {
+ if (cast->getCastKind() == CK_LValueToRValue)
+ return false;
+ return isBlockVarRef(cast->getSubExpr());
+
+ // Handle unary operators. Again, just aggressively look through
+ // it, ignoring the operation.
+ } else if (const UnaryOperator *uop = dyn_cast<UnaryOperator>(E)) {
+ return isBlockVarRef(uop->getSubExpr());
+
+ // Look into the base of a field access.
+ } else if (const MemberExpr *mem = dyn_cast<MemberExpr>(E)) {
+ return isBlockVarRef(mem->getBase());
+
+ // Look into the base of a subscript.
+ } else if (const ArraySubscriptExpr *sub = dyn_cast<ArraySubscriptExpr>(E)) {
+ return isBlockVarRef(sub->getBase());
+ }
+
+ return false;
}
void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
@@ -686,20 +760,26 @@
E->getRHS()->getType())
&& "Invalid assignment");
- if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getLHS()))
- if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
- if (VD->hasAttr<BlocksAttr>() &&
- E->getRHS()->HasSideEffects(CGF.getContext())) {
- // When __block variable on LHS, the RHS must be evaluated first
- // as it may change the 'forwarding' field via call to Block_copy.
- LValue RHS = CGF.EmitLValue(E->getRHS());
- LValue LHS = CGF.EmitLValue(E->getLHS());
- Dest = AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed,
- needsGC(E->getLHS()->getType()),
- AggValueSlot::IsAliased);
- EmitFinalDestCopy(E, RHS, true);
- return;
- }
+ // If the LHS might be a __block variable, and the RHS can
+ // potentially cause a block copy, we need to evaluate the RHS first
+ // so that the assignment goes the right place.
+ // This is pretty semantically fragile.
+ if (isBlockVarRef(E->getLHS()) &&
+ E->getRHS()->HasSideEffects(CGF.getContext())) {
+ // Ensure that we have a destination, and evaluate the RHS into that.
+ EnsureDest(E->getRHS()->getType());
+ Visit(E->getRHS());
+
+ // Now emit the LHS and copy into it.
+ LValue LHS = CGF.EmitLValue(E->getLHS());
+
+ EmitCopy(E->getLHS()->getType(),
+ AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed,
+ needsGC(E->getLHS()->getType()),
+ AggValueSlot::IsAliased),
+ Dest);
+ return;
+ }
LValue LHS = CGF.EmitLValue(E->getLHS());
@@ -708,8 +788,10 @@
AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed,
needsGC(E->getLHS()->getType()),
AggValueSlot::IsAliased);
- CGF.EmitAggExpr(E->getRHS(), LHSSlot, false);
- EmitFinalDestCopy(E, LHS, true);
+ CGF.EmitAggExpr(E->getRHS(), LHSSlot);
+
+ // Copy into the destination if the assignment isn't ignored.
+ EmitFinalDestCopy(E->getType(), LHS);
}
void AggExprEmitter::
@@ -762,14 +844,14 @@
return;
}
- EmitFinalDestCopy(VE, CGF.MakeAddrLValue(ArgPtr, VE->getType()));
+ EmitFinalDestCopy(VE->getType(), CGF.MakeAddrLValue(ArgPtr, VE->getType()));
}
void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
// Ensure that we have a slot, but if we already do, remember
// whether it was externally destructed.
bool wasExternallyDestructed = Dest.isExternallyDestructed();
- Dest = EnsureSlot(E->getType());
+ EnsureDest(E->getType());
// We're going to push a destructor if there isn't already one.
Dest.setExternallyDestructed();
@@ -904,7 +986,7 @@
llvm::GlobalVariable* GV =
new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,
llvm::GlobalValue::InternalLinkage, C, "");
- EmitFinalDestCopy(E, CGF.MakeAddrLValue(GV, E->getType()));
+ EmitFinalDestCopy(E->getType(), CGF.MakeAddrLValue(GV, E->getType()));
return;
}
#endif
@@ -1164,8 +1246,7 @@
/// type. The result is computed into DestPtr. Note that if DestPtr is null,
/// the value of the aggregate expression is not needed. If VolatileDest is
/// true, DestPtr cannot be 0.
-void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot,
- bool IgnoreResult) {
+void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot) {
assert(E && hasAggregateLLVMType(E->getType()) &&
"Invalid aggregate expression to emit");
assert((Slot.getAddr() != 0 || Slot.isIgnored()) &&
@@ -1174,7 +1255,7 @@
// Optimize the slot if possible.
CheckAggExprForMemSetUse(Slot, E, *this);
- AggExprEmitter(*this, Slot, IgnoreResult).Visit(const_cast<Expr*>(E));
+ AggExprEmitter(*this, Slot).Visit(const_cast<Expr*>(E));
}
LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
@@ -1189,7 +1270,8 @@
void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
llvm::Value *SrcPtr, QualType Ty,
- bool isVolatile, unsigned Alignment) {
+ bool isVolatile,
+ CharUnits alignment) {
assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
if (getContext().getLangOpts().CPlusPlus) {
@@ -1222,8 +1304,8 @@
std::pair<CharUnits, CharUnits> TypeInfo =
getContext().getTypeInfoInChars(Ty);
- if (!Alignment)
- Alignment = TypeInfo.second.getQuantity();
+ if (alignment.isZero())
+ alignment = TypeInfo.second;
// FIXME: Handle variable sized types.
@@ -1281,7 +1363,7 @@
Builder.CreateMemCpy(DestPtr, SrcPtr,
llvm::ConstantInt::get(IntPtrTy,
TypeInfo.first.getQuantity()),
- Alignment, isVolatile);
+ alignment.getQuantity(), isVolatile);
}
void CodeGenFunction::MaybeEmitStdInitializerListCleanup(llvm::Value *loc,
Modified: cfe/branches/tooling/lib/CodeGen/CGValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGValue.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGValue.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CGValue.h Tue Jul 3 11:18:37 2012
@@ -389,7 +389,8 @@
return AV;
}
- static AggValueSlot forLValue(LValue LV, IsDestructed_t isDestructed,
+ static AggValueSlot forLValue(const LValue &LV,
+ IsDestructed_t isDestructed,
NeedsGCBarriers_t needsGC,
IsAliased_t isAliased,
IsZeroed_t isZeroed = IsNotZeroed) {
Modified: cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h Tue Jul 3 11:18:37 2012
@@ -1566,6 +1566,7 @@
return LValue::MakeAddr(V, T, Alignment, getContext(),
CGM.getTBAAInfo(T));
}
+
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) {
CharUnits Alignment;
if (!T->isIncompleteType())
@@ -1622,8 +1623,8 @@
///
/// \param IgnoreResult - True if the resulting value isn't used.
RValue EmitAnyExpr(const Expr *E,
- AggValueSlot AggSlot = AggValueSlot::ignored(),
- bool IgnoreResult = false);
+ AggValueSlot aggSlot = AggValueSlot::ignored(),
+ bool ignoreResult = false);
// EmitVAListRef - Emit a "reference" to a va_list; this is either the address
// or the value of the expression, depending on how va_list is defined.
@@ -1649,7 +1650,7 @@
/// volatile.
void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr,
QualType EltTy, bool isVolatile=false,
- unsigned Alignment = 0);
+ CharUnits Alignment = CharUnits::Zero());
/// StartBlock - Start new block named N. If insert block is a dummy block
/// then reuse it.
@@ -2363,7 +2364,7 @@
/// EmitAggExpr - Emit the computation of the specified expression
/// of aggregate type. The result is computed into the given slot,
/// which may be null to indicate that the value is not needed.
- void EmitAggExpr(const Expr *E, AggValueSlot AS, bool IgnoreResult = false);
+ void EmitAggExpr(const Expr *E, AggValueSlot AS);
/// EmitAggExprToLValue - Emit the computation of the specified expression of
/// aggregate type into a temporary LValue.
Modified: cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp Tue Jul 3 11:18:37 2012
@@ -1111,6 +1111,7 @@
} else if (getLangOpts().CPlusPlus && D.getDecl()) {
// Look for a declaration that's lexically in a record.
const FunctionDecl *FD = cast<FunctionDecl>(D.getDecl());
+ FD = FD->getMostRecentDecl();
do {
if (isa<CXXRecordDecl>(FD->getLexicalDeclContext())) {
if (FD->isImplicit() && !ForVTable) {
Modified: cfe/branches/tooling/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/Driver.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/Driver.cpp (original)
+++ cfe/branches/tooling/lib/Driver/Driver.cpp Tue Jul 3 11:18:37 2012
@@ -503,7 +503,6 @@
// Strip away options not necessary to reproduce the crash.
// FIXME: This doesn't work with quotes (e.g., -D "foo bar").
SmallVector<std::string, 16> Flag;
- Flag.push_back("-D ");
Flag.push_back("-F");
Flag.push_back("-I ");
Flag.push_back("-o ");
Modified: cfe/branches/tooling/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/ASTUnit.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/ASTUnit.cpp Tue Jul 3 11:18:37 2012
@@ -214,6 +214,7 @@
PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0),
NumWarningsInPreamble(0),
ShouldCacheCodeCompletionResults(false),
+ IncludeBriefCommentsInCodeCompletion(false),
CompletionCacheTopLevelHashValue(0),
PreambleTopLevelHashValue(0),
CurrentTopLevelHashValue(0),
@@ -358,7 +359,8 @@
CachedCodeCompletionResult CachedResult;
CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema,
*CachedCompletionAllocator,
- getCodeCompletionTUInfo());
+ getCodeCompletionTUInfo(),
+ IncludeBriefCommentsInCodeCompletion);
CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration,
Ctx->getLangOpts(),
IsNestedNameSpecifier);
@@ -423,7 +425,8 @@
CachedResult.Completion
= Results[I].CreateCodeCompletionString(*TheSema,
*CachedCompletionAllocator,
- getCodeCompletionTUInfo());
+ getCodeCompletionTUInfo(),
+ IncludeBriefCommentsInCodeCompletion);
CachedResult.ShowInContexts = RemainingContexts;
CachedResult.Priority = CCP_NestedNameSpecifier;
CachedResult.TypeClass = STC_Void;
@@ -445,7 +448,8 @@
CachedResult.Completion
= Results[I].CreateCodeCompletionString(*TheSema,
*CachedCompletionAllocator,
- getCodeCompletionTUInfo());
+ getCodeCompletionTUInfo(),
+ IncludeBriefCommentsInCodeCompletion);
CachedResult.ShowInContexts
= (1 << (CodeCompletionContext::CCC_TopLevel - 1))
| (1 << (CodeCompletionContext::CCC_ObjCInterface - 1))
@@ -1683,6 +1687,7 @@
bool CaptureDiagnostics,
bool PrecompilePreamble,
bool CacheCodeCompletionResults,
+ bool IncludeBriefCommentsInCodeCompletion,
OwningPtr<ASTUnit> *ErrAST) {
assert(CI && "A CompilerInvocation is required");
@@ -1704,6 +1709,8 @@
AST->PreambleRebuildCounter = 2;
AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
+ AST->IncludeBriefCommentsInCodeCompletion
+ = IncludeBriefCommentsInCodeCompletion;
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
@@ -1850,7 +1857,8 @@
bool CaptureDiagnostics,
bool PrecompilePreamble,
TranslationUnitKind TUKind,
- bool CacheCodeCompletionResults) {
+ bool CacheCodeCompletionResults,
+ bool IncludeBriefCommentsInCodeCompletion) {
// Create the AST unit.
OwningPtr<ASTUnit> AST;
AST.reset(new ASTUnit(false));
@@ -1860,6 +1868,8 @@
AST->CaptureDiagnostics = CaptureDiagnostics;
AST->TUKind = TUKind;
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
+ AST->IncludeBriefCommentsInCodeCompletion
+ = IncludeBriefCommentsInCodeCompletion;
AST->Invocation = CI;
// Recover resources if we crash before exiting this method.
@@ -1884,6 +1894,7 @@
bool PrecompilePreamble,
TranslationUnitKind TUKind,
bool CacheCodeCompletionResults,
+ bool IncludeBriefCommentsInCodeCompletion,
bool AllowPCHWithCompilerErrors,
bool SkipFunctionBodies,
OwningPtr<ASTUnit> *ErrAST) {
@@ -1943,6 +1954,8 @@
AST->CaptureDiagnostics = CaptureDiagnostics;
AST->TUKind = TUKind;
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
+ AST->IncludeBriefCommentsInCodeCompletion
+ = IncludeBriefCommentsInCodeCompletion;
AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
AST->StoredDiagnostics.swap(StoredDiagnostics);
AST->Invocation = CI;
@@ -2041,10 +2054,9 @@
public:
AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
- bool IncludeMacros, bool IncludeCodePatterns,
- bool IncludeGlobals)
- : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals,
- Next.isOutputBinary()), AST(AST), Next(Next)
+ const CodeCompleteOptions &CodeCompleteOpts)
+ : CodeCompleteConsumer(CodeCompleteOpts, Next.isOutputBinary()),
+ AST(AST), Next(Next)
{
// Compute the set of contexts in which we will look when we don't have
// any information about the specific context.
@@ -2274,6 +2286,7 @@
unsigned NumRemappedFiles,
bool IncludeMacros,
bool IncludeCodePatterns,
+ bool IncludeBriefComments,
CodeCompleteConsumer &Consumer,
DiagnosticsEngine &Diag, LangOptions &LangOpts,
SourceManager &SourceMgr, FileManager &FileMgr,
@@ -2290,13 +2303,17 @@
CCInvocation(new CompilerInvocation(*Invocation));
FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();
+ CodeCompleteOptions &CodeCompleteOpts = FrontendOpts.CodeCompleteOpts;
PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();
- FrontendOpts.ShowMacrosInCodeCompletion
- = IncludeMacros && CachedCompletionResults.empty();
- FrontendOpts.ShowCodePatternsInCodeCompletion = IncludeCodePatterns;
- FrontendOpts.ShowGlobalSymbolsInCodeCompletion
- = CachedCompletionResults.empty();
+ CodeCompleteOpts.IncludeMacros = IncludeMacros &&
+ CachedCompletionResults.empty();
+ CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns;
+ CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();
+ CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments;
+
+ assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
+
FrontendOpts.CodeCompletionAt.FileName = File;
FrontendOpts.CodeCompletionAt.Line = Line;
FrontendOpts.CodeCompletionAt.Column = Column;
@@ -2365,10 +2382,7 @@
// Use the code completion consumer we were given, but adding any cached
// code-completion results.
AugmentedCodeCompleteConsumer *AugmentedConsumer
- = new AugmentedCodeCompleteConsumer(*this, Consumer,
- FrontendOpts.ShowMacrosInCodeCompletion,
- FrontendOpts.ShowCodePatternsInCodeCompletion,
- FrontendOpts.ShowGlobalSymbolsInCodeCompletion);
+ = new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts);
Clang->setCodeCompletionConsumer(AugmentedConsumer);
Clang->getFrontendOpts().SkipFunctionBodies = true;
Modified: cfe/branches/tooling/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/CompilerInstance.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/CompilerInstance.cpp Tue Jul 3 11:18:37 2012
@@ -387,9 +387,7 @@
setCodeCompletionConsumer(
createCodeCompletionConsumer(getPreprocessor(),
Loc.FileName, Loc.Line, Loc.Column,
- getFrontendOpts().ShowMacrosInCodeCompletion,
- getFrontendOpts().ShowCodePatternsInCodeCompletion,
- getFrontendOpts().ShowGlobalSymbolsInCodeCompletion,
+ getFrontendOpts().CodeCompleteOpts,
llvm::outs()));
if (!CompletionConsumer)
return;
@@ -415,16 +413,13 @@
const std::string &Filename,
unsigned Line,
unsigned Column,
- bool ShowMacros,
- bool ShowCodePatterns,
- bool ShowGlobals,
+ const CodeCompleteOptions &Opts,
raw_ostream &OS) {
if (EnableCodeCompletion(PP, Filename, Line, Column))
return 0;
// Set up the creation routine for code-completion.
- return new PrintingCodeCompleteConsumer(ShowMacros, ShowCodePatterns,
- ShowGlobals, OS);
+ return new PrintingCodeCompleteConsumer(Opts, OS);
}
void CompilerInstance::createSema(TranslationUnitKind TUKind,
Modified: cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp Tue Jul 3 11:18:37 2012
@@ -470,6 +470,18 @@
Res.push_back("-working-directory", Opts.WorkingDir);
}
+static void CodeCompleteOptionsToArgs(const CodeCompleteOptions &Opts,
+ ToArgsList &Res) {
+ if (Opts.IncludeMacros)
+ Res.push_back("-code-completion-macros");
+ if (Opts.IncludeCodePatterns)
+ Res.push_back("-code-completion-patterns");
+ if (!Opts.IncludeGlobals)
+ Res.push_back("-no-code-completion-globals");
+ if (Opts.IncludeBriefComments)
+ Res.push_back("-code-completion-brief-comments");
+}
+
static void FrontendOptsToArgs(const FrontendOptions &Opts, ToArgsList &Res) {
if (Opts.DisableFree)
Res.push_back("-disable-free");
@@ -477,12 +489,6 @@
Res.push_back("-relocatable-pch");
if (Opts.ShowHelp)
Res.push_back("-help");
- if (Opts.ShowMacrosInCodeCompletion)
- Res.push_back("-code-completion-macros");
- if (Opts.ShowCodePatternsInCodeCompletion)
- Res.push_back("-code-completion-patterns");
- if (!Opts.ShowGlobalSymbolsInCodeCompletion)
- Res.push_back("-no-code-completion-globals");
if (Opts.ShowStats)
Res.push_back("-print-stats");
if (Opts.ShowTimers)
@@ -510,6 +516,7 @@
Res.push_back("-arcmt-migrate");
break;
}
+ CodeCompleteOptionsToArgs(Opts.CodeCompleteOpts, Res);
if (!Opts.MTMigrateDir.empty())
Res.push_back("-mt-migrate-directory", Opts.MTMigrateDir);
if (!Opts.ARCMTMigrateReportOut.empty())
@@ -1517,11 +1524,6 @@
Opts.Plugins = Args.getAllArgValues(OPT_load);
Opts.RelocatablePCH = Args.hasArg(OPT_relocatable_pch);
Opts.ShowHelp = Args.hasArg(OPT_help);
- Opts.ShowMacrosInCodeCompletion = Args.hasArg(OPT_code_completion_macros);
- Opts.ShowCodePatternsInCodeCompletion
- = Args.hasArg(OPT_code_completion_patterns);
- Opts.ShowGlobalSymbolsInCodeCompletion
- = !Args.hasArg(OPT_no_code_completion_globals);
Opts.ShowStats = Args.hasArg(OPT_print_stats);
Opts.ShowTimers = Args.hasArg(OPT_ftime_report);
Opts.ShowVersion = Args.hasArg(OPT_version);
@@ -1531,6 +1533,16 @@
Opts.FixOnlyWarnings = Args.hasArg(OPT_fix_only_warnings);
Opts.FixAndRecompile = Args.hasArg(OPT_fixit_recompile);
Opts.FixToTemporaries = Args.hasArg(OPT_fixit_to_temp);
+
+ Opts.CodeCompleteOpts.IncludeMacros
+ = Args.hasArg(OPT_code_completion_macros);
+ Opts.CodeCompleteOpts.IncludeCodePatterns
+ = Args.hasArg(OPT_code_completion_patterns);
+ Opts.CodeCompleteOpts.IncludeGlobals
+ = !Args.hasArg(OPT_no_code_completion_globals);
+ Opts.CodeCompleteOpts.IncludeBriefComments
+ = Args.hasArg(OPT_code_completion_brief_comments);
+
Opts.OverrideRecordLayoutsFile
= Args.getLastArgValue(OPT_foverride_record_layout_EQ);
if (const Arg *A = Args.getLastArg(OPT_arcmt_check,
@@ -2014,7 +2026,7 @@
Opts.AccessControl = !Args.hasArg(OPT_fno_access_control);
Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
Opts.MathErrno = Args.hasArg(OPT_fmath_errno);
- Opts.InstantiationDepth = Args.getLastArgIntValue(OPT_ftemplate_depth, 1024,
+ Opts.InstantiationDepth = Args.getLastArgIntValue(OPT_ftemplate_depth, 512,
Diags);
Opts.ConstexprCallDepth = Args.getLastArgIntValue(OPT_fconstexpr_depth, 512,
Diags);
Modified: cfe/branches/tooling/lib/Headers/bmiintrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Headers/bmiintrin.h?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Headers/bmiintrin.h (original)
+++ cfe/branches/tooling/lib/Headers/bmiintrin.h Tue Jul 3 11:18:37 2012
@@ -33,7 +33,7 @@
#define __BMIINTRIN_H
static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
-__tzcnt16(unsigned short __X)
+__tzcnt_u16(unsigned short __X)
{
return __builtin_ctzs(__X);
}
@@ -69,7 +69,7 @@
}
static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
-__tzcnt32(unsigned int __X)
+__tzcnt_u32(unsigned int __X)
{
return __builtin_ctz(__X);
}
@@ -106,7 +106,7 @@
}
static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
-__tzcnt64(unsigned long long __X)
+__tzcnt_u64(unsigned long long __X)
{
return __builtin_ctzll(__X);
}
Modified: cfe/branches/tooling/lib/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/LiteralSupport.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/LiteralSupport.cpp (original)
+++ cfe/branches/tooling/lib/Lex/LiteralSupport.cpp Tue Jul 3 11:18:37 2012
@@ -1330,45 +1330,10 @@
}
}
-
/// copyStringFragment - This function copies from Start to End into ResultPtr.
/// Performs widening for multi-byte characters.
bool StringLiteralParser::CopyStringFragment(StringRef Fragment) {
- assert(CharByteWidth==1 || CharByteWidth==2 || CharByteWidth==4);
- ConversionResult result = conversionOK;
- // Copy the character span over.
- if (CharByteWidth == 1) {
- if (!isLegalUTF8String(reinterpret_cast<const UTF8*>(Fragment.begin()),
- reinterpret_cast<const UTF8*>(Fragment.end())))
- result = sourceIllegal;
- memcpy(ResultPtr, Fragment.data(), Fragment.size());
- ResultPtr += Fragment.size();
- } else if (CharByteWidth == 2) {
- UTF8 const *sourceStart = (UTF8 const *)Fragment.data();
- // FIXME: Make the type of the result buffer correct instead of
- // using reinterpret_cast.
- UTF16 *targetStart = reinterpret_cast<UTF16*>(ResultPtr);
- ConversionFlags flags = strictConversion;
- result = ConvertUTF8toUTF16(
- &sourceStart,sourceStart + Fragment.size(),
- &targetStart,targetStart + 2*Fragment.size(),flags);
- if (result==conversionOK)
- ResultPtr = reinterpret_cast<char*>(targetStart);
- } else if (CharByteWidth == 4) {
- UTF8 const *sourceStart = (UTF8 const *)Fragment.data();
- // FIXME: Make the type of the result buffer correct instead of
- // using reinterpret_cast.
- UTF32 *targetStart = reinterpret_cast<UTF32*>(ResultPtr);
- ConversionFlags flags = strictConversion;
- result = ConvertUTF8toUTF32(
- &sourceStart,sourceStart + Fragment.size(),
- &targetStart,targetStart + 4*Fragment.size(),flags);
- if (result==conversionOK)
- ResultPtr = reinterpret_cast<char*>(targetStart);
- }
- assert((result != targetExhausted)
- && "ConvertUTF8toUTFXX exhausted target buffer");
- return result != conversionOK;
+ return !ConvertUTF8toWide(CharByteWidth, Fragment, ResultPtr);
}
bool StringLiteralParser::DiagnoseBadString(const Token &Tok) {
Modified: cfe/branches/tooling/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseDecl.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseDecl.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseDecl.cpp Tue Jul 3 11:18:37 2012
@@ -1379,6 +1379,14 @@
bool ExpectSemi = Context != Declarator::ForContext;
+ if (CurParsedObjCImpl && D.isFunctionDeclarator() &&
+ Tok.is(tok::l_brace)) {
+ // Consume the tokens and store them for later parsing.
+ StashAwayMethodOrFunctionBodyTokens(FirstDecl);
+ CurParsedObjCImpl->HasCFunction = true;
+ ExpectSemi = false;
+ }
+
// If we don't have a comma, it is either the end of the list (a ';') or an
// error, bail out.
while (Tok.is(tok::comma)) {
@@ -3067,9 +3075,10 @@
TypeResult BaseType;
// Parse the fixed underlying type.
+ bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
if (AllowFixedUnderlyingType && Tok.is(tok::colon)) {
bool PossibleBitfield = false;
- if (getCurScope()->getFlags() & Scope::ClassScope) {
+ if (CanBeBitfield) {
// If we're in class scope, this can either be an enum declaration with
// an underlying type, or a declaration of a bitfield member. We try to
// use a simple disambiguation scheme first to catch the common cases
@@ -3158,7 +3167,8 @@
}
} else if (DSC != DSC_type_specifier &&
(Tok.is(tok::semi) ||
- (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier()))) {
+ (Tok.isAtStartOfLine() &&
+ !isValidAfterTypeSpecifier(CanBeBitfield)))) {
TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
if (Tok.isNot(tok::semi)) {
// A semicolon was missing after this declaration. Diagnose and recover.
@@ -3366,7 +3376,8 @@
// The next token must be valid after an enum definition. If not, a ';'
// was probably forgotten.
- if (!isValidAfterTypeSpecifier()) {
+ bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
+ if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum");
// Push this token back into the preprocessor and change our current token
// to ';' so that the rest of the code recovers as though there were an
Modified: cfe/branches/tooling/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseDeclCXX.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseDeclCXX.cpp Tue Jul 3 11:18:37 2012
@@ -929,7 +929,7 @@
/// Determine whether the following tokens are valid after a type-specifier
/// which could be a standalone declaration. This will conservatively return
/// true if there's any doubt, and is appropriate for insert-';' fixits.
-bool Parser::isValidAfterTypeSpecifier() {
+bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
// This switch enumerates the valid "follow" set for type-specifiers.
switch (Tok.getKind()) {
default: break;
@@ -944,6 +944,8 @@
case tok::l_paren: // struct foo {...} ( x);
case tok::comma: // __builtin_offsetof(struct foo{...} ,
return true;
+ case tok::colon:
+ return CouldBeBitfield; // enum E { ... } : 2;
// Type qualifiers
case tok::kw_const: // struct foo {...} const x;
case tok::kw_volatile: // struct foo {...} volatile x;
@@ -1236,7 +1238,7 @@
}
} else if (DSC != DSC_type_specifier &&
(Tok.is(tok::semi) ||
- (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier()))) {
+ (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) {
TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
if (Tok.isNot(tok::semi)) {
// A semicolon was missing after this declaration. Diagnose and recover.
@@ -1466,7 +1468,7 @@
// In a template-declaration which defines a class, no declarator
// is permitted.
if (TUK == Sema::TUK_Definition &&
- (TemplateInfo.Kind || !isValidAfterTypeSpecifier())) {
+ (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) {
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
TagType == DeclSpec::TST_class ? "class" :
TagType == DeclSpec::TST_struct ? "struct" : "union");
Modified: cfe/branches/tooling/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseObjc.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseObjc.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseObjc.cpp Tue Jul 3 11:18:37 2012
@@ -1575,10 +1575,16 @@
assert(!Finished);
P.Actions.DefaultSynthesizeProperties(P.getCurScope(), Dcl);
for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
- P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i]);
+ P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
+ true/*Methods*/);
P.Actions.ActOnAtEnd(P.getCurScope(), AtEnd);
+ if (HasCFunction)
+ for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
+ P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
+ false/*c-functions*/);
+
/// \brief Clear and free the cached objc methods.
for (LateParsedObjCMethodContainer::iterator
I = LateParsedObjCMethods.begin(),
@@ -1915,6 +1921,19 @@
AutoreleasePoolBody.take());
}
+/// StashAwayMethodOrFunctionBodyTokens - Consume the tokens and store them
+/// for later parsing.
+void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
+ LexedMethod* LM = new LexedMethod(this, MDecl);
+ CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
+ CachedTokens &Toks = LM->Toks;
+ // Begin by storing the '{' token.
+ Toks.push_back(Tok);
+ ConsumeBrace();
+ // Consume everything up to (and including) the matching right brace.
+ ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
+}
+
/// objc-method-def: objc-method-proto ';'[opt] '{' body '}'
///
Decl *Parser::ParseObjCMethodDefinition() {
@@ -1955,15 +1974,7 @@
if (CurParsedObjCImpl) {
// Consume the tokens and store them for later parsing.
- LexedMethod* LM = new LexedMethod(this, MDecl);
- CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
- CachedTokens &Toks = LM->Toks;
- // Begin by storing the '{' token.
- Toks.push_back(Tok);
- ConsumeBrace();
- // Consume everything up to (and including) the matching right brace.
- ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
-
+ StashAwayMethodOrFunctionBodyTokens(MDecl);
} else {
ConsumeBrace();
SkipUntil(tok::r_brace, /*StopAtSemi=*/false);
@@ -2821,8 +2832,15 @@
T.getCloseLocation()));
}
-Decl *Parser::ParseLexedObjCMethodDefs(LexedMethod &LM) {
-
+void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
+ // MCDecl might be null due to error in method or c-function prototype, etc.
+ Decl *MCDecl = LM.D;
+ bool skip = MCDecl &&
+ ((parseMethod && !Actions.isObjCMethodDecl(MCDecl)) ||
+ (!parseMethod && Actions.isObjCMethodDecl(MCDecl)));
+ if (skip)
+ return;
+
// Save the current token position.
SourceLocation OrigLoc = Tok.getLocation();
@@ -2832,24 +2850,25 @@
LM.Toks.push_back(Tok);
PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
- // MDecl might be null due to error in method prototype, etc.
- Decl *MDecl = LM.D;
// Consume the previously pushed token.
ConsumeAnyToken();
assert(Tok.is(tok::l_brace) && "Inline objective-c method not starting with '{'");
SourceLocation BraceLoc = Tok.getLocation();
- // Enter a scope for the method body.
+ // Enter a scope for the method or c-fucntion body.
ParseScope BodyScope(this,
- Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope);
+ parseMethod
+ ? Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope
+ : Scope::FnScope|Scope::DeclScope);
- // Tell the actions module that we have entered a method definition with the
- // specified Declarator for the method.
- Actions.ActOnStartOfObjCMethodDef(getCurScope(), MDecl);
+ // Tell the actions module that we have entered a method or c-function definition
+ // with the specified Declarator for the method/function.
+ Actions.ActOnStartOfObjCMethodOrCFunctionDef(getCurScope(), MCDecl, parseMethod);
if (SkipFunctionBodies && trySkippingFunctionBody()) {
BodyScope.Exit();
- return Actions.ActOnFinishFunctionBody(MDecl, 0);
+ (void)Actions.ActOnFinishFunctionBody(MCDecl, 0);
+ return;
}
StmtResult FnBody(ParseCompoundStatementBody());
@@ -2864,7 +2883,7 @@
// Leave the function body scope.
BodyScope.Exit();
- MDecl = Actions.ActOnFinishFunctionBody(MDecl, FnBody.take());
+ (void)Actions.ActOnFinishFunctionBody(MCDecl, FnBody.take());
if (Tok.getLocation() != OrigLoc) {
// Due to parsing error, we either went over the cached tokens or
@@ -2878,5 +2897,5 @@
ConsumeAnyToken();
}
- return MDecl;
+ return;
}
Modified: cfe/branches/tooling/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/Parser.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/Parser.cpp (original)
+++ cfe/branches/tooling/lib/Parse/Parser.cpp Tue Jul 3 11:18:37 2012
@@ -766,14 +766,16 @@
if (KW.is(tok::kw_default) || KW.is(tok::kw_delete))
return false;
}
-
+
return Tok.is(tok::equal) || // int X()= -> not a function def
Tok.is(tok::comma) || // int X(), -> not a function def
Tok.is(tok::semi) || // int X(); -> not a function def
Tok.is(tok::kw_asm) || // int X() __asm__ -> not a function def
Tok.is(tok::kw___attribute) || // int X() __attr__ -> not a function def
(getLangOpts().CPlusPlus &&
- Tok.is(tok::l_paren)); // int X(0) -> not a function def [C++]
+ Tok.is(tok::l_paren)) || // int X(0) -> not a function def [C++]
+ (CurParsedObjCImpl &&
+ Tok.is(tok::l_brace)); // C-function nested in an @implementation
}
/// \brief Determine whether the current token, if it occurs after a
Modified: cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/branches/tooling/lib/Sema/AnalysisBasedWarnings.cpp Tue Jul 3 11:18:37 2012
@@ -1061,6 +1061,9 @@
case LEK_LockedAtEndOfFunction:
DiagID = diag::warn_no_unlock;
break;
+ case LEK_NotLockedAtEndOfFunction:
+ DiagID = diag::warn_expecting_locked;
+ break;
}
if (LocEndOfScope.isInvalid())
LocEndOfScope = FunEndLocation;
Modified: cfe/branches/tooling/lib/Sema/CodeCompleteConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/CodeCompleteConsumer.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/CodeCompleteConsumer.cpp (original)
+++ cfe/branches/tooling/lib/Sema/CodeCompleteConsumer.cpp Tue Jul 3 11:18:37 2012
@@ -194,10 +194,11 @@
const char **Annotations,
unsigned NumAnnotations,
CXCursorKind ParentKind,
- StringRef ParentName)
+ StringRef ParentName,
+ const char *BriefComment)
: NumChunks(NumChunks), NumAnnotations(NumAnnotations),
Priority(Priority), Availability(Availability), ParentKind(ParentKind),
- ParentName(ParentName)
+ ParentName(ParentName), BriefComment(BriefComment)
{
assert(NumChunks <= 0xffff);
assert(NumAnnotations <= 0xffff);
@@ -338,7 +339,7 @@
= new (Mem) CodeCompletionString(Chunks.data(), Chunks.size(),
Priority, Availability,
Annotations.data(), Annotations.size(),
- ParentKind, ParentName);
+ ParentKind, ParentName, BriefComment);
Chunks.clear();
return Result;
}
@@ -394,6 +395,10 @@
ParentName = getCodeCompletionTUInfo().getParentName(DC);
}
+void CodeCompletionBuilder::addBriefComment(StringRef Comment) {
+ BriefComment = Allocator.CopyString(Comment);
+}
+
unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl *ND) {
if (!ND)
return CCP_Unlikely;
@@ -474,8 +479,11 @@
OS << " (Hidden)";
if (CodeCompletionString *CCS
= Results[I].CreateCodeCompletionString(SemaRef, getAllocator(),
- CCTUInfo)) {
+ CCTUInfo,
+ includeBriefComments())) {
OS << " : " << CCS->getAsString();
+ if (const char *BriefComment = CCS->getBriefComment())
+ OS << " : " << BriefComment;
}
OS << '\n';
@@ -489,7 +497,8 @@
OS << Results[I].Macro->getName();
if (CodeCompletionString *CCS
= Results[I].CreateCodeCompletionString(SemaRef, getAllocator(),
- CCTUInfo)) {
+ CCTUInfo,
+ includeBriefComments())) {
OS << " : " << CCS->getAsString();
}
OS << '\n';
Modified: cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp Tue Jul 3 11:18:37 2012
@@ -2453,8 +2453,10 @@
CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S,
CodeCompletionAllocator &Allocator,
- CodeCompletionTUInfo &CCTUInfo) {
- return CreateCodeCompletionString(S.Context, S.PP, Allocator, CCTUInfo);
+ CodeCompletionTUInfo &CCTUInfo,
+ bool IncludeBriefComments) {
+ return CreateCodeCompletionString(S.Context, S.PP, Allocator, CCTUInfo,
+ IncludeBriefComments);
}
/// \brief If possible, create a new code completion string for the given
@@ -2467,7 +2469,8 @@
CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
Preprocessor &PP,
CodeCompletionAllocator &Allocator,
- CodeCompletionTUInfo &CCTUInfo) {
+ CodeCompletionTUInfo &CCTUInfo,
+ bool IncludeBriefComments) {
CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability);
PrintingPolicy Policy = getCompletionPrintingPolicy(Ctx, PP);
@@ -2537,7 +2540,14 @@
assert(Kind == RK_Declaration && "Missed a result kind?");
NamedDecl *ND = Declaration;
Result.addParentContext(ND->getDeclContext());
-
+
+ if (IncludeBriefComments) {
+ // Add documentation comment, if it exists.
+ if (const RawComment *RC = Ctx.getRawCommentForDecl(ND)) {
+ Result.addBriefComment(RC->getBriefText(Ctx));
+ }
+ }
+
if (StartsNestedNameSpecifier) {
Result.AddTypedTextChunk(
Result.getAllocator().CopyString(ND->getNameAsString()));
Modified: cfe/branches/tooling/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDecl.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDecl.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDecl.cpp Tue Jul 3 11:18:37 2012
@@ -7659,7 +7659,12 @@
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(FD))
MarkVTableUsed(FD->getLocation(), Constructor->getParent());
- computeNRVO(Body, getCurFunction());
+ // Try to apply the named return value optimization. We have to check
+ // if we can do this here because lambdas keep return statements around
+ // to deduce an implicit return type.
+ if (getLangOpts().CPlusPlus && FD->getResultType()->isRecordType() &&
+ !FD->isDependentContext())
+ computeNRVO(Body, getCurFunction());
}
assert((FD == getCurFunctionDecl() || getCurLambda()->CallOperator == FD) &&
Modified: cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp Tue Jul 3 11:18:37 2012
@@ -1119,6 +1119,8 @@
Virtual, Access, TInfo,
EllipsisLoc))
return BaseSpec;
+ else
+ Class->setInvalidDecl();
return true;
}
Modified: cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp Tue Jul 3 11:18:37 2012
@@ -265,12 +265,36 @@
AddFactoryMethodToGlobalPool(MDecl, true);
}
-/// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
-/// and user declared, in the method definition's AST.
-void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
- assert(getCurMethodDecl() == 0 && "Method parsing confused");
+/// ActOnStartOfObjCMethodOrCFunctionDef - This routine sets up parameters; invisible
+/// and user declared, in the method definition's AST. This routine is also called
+/// for C-functions defined in an Objective-c class implementation.
+void Sema::ActOnStartOfObjCMethodOrCFunctionDef(Scope *FnBodyScope, Decl *D,
+ bool parseMethod) {
+ assert((getCurMethodDecl() == 0 && getCurFunctionDecl() == 0) &&
+ "Method/c-function parsing confused");
+ if (!parseMethod) {
+ FunctionDecl *FDecl = dyn_cast_or_null<FunctionDecl>(D);
+ // If we don't have a valid c-function decl, simply return.
+ if (!FDecl)
+ return;
+ PushDeclContext(FnBodyScope, FDecl);
+ PushFunctionScope();
+
+ for (FunctionDecl::param_const_iterator PI = FDecl->param_begin(),
+ E = FDecl->param_end(); PI != E; ++PI) {
+ ParmVarDecl *Param = (*PI);
+ if (!Param->isInvalidDecl() &&
+ RequireCompleteType(Param->getLocation(), Param->getType(),
+ diag::err_typecheck_decl_incomplete_type))
+ Param->setInvalidDecl();
+ if ((*PI)->getIdentifier())
+ PushOnScopeChains(*PI, FnBodyScope);
+ }
+ return;
+ }
+
ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
-
+
// If we don't have a valid method decl, simply return.
if (!MDecl)
return;
Modified: cfe/branches/tooling/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaExpr.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaExpr.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaExpr.cpp Tue Jul 3 11:18:37 2012
@@ -7558,25 +7558,25 @@
return true;
}
-static void CheckIdentityMemvarAssignment(Expr *LHSExpr, Expr *RHSExpr,
- SourceLocation Loc,
- Sema &Sema) {
- // C / C++ memvars
+static void CheckIdentityFieldAssignment(Expr *LHSExpr, Expr *RHSExpr,
+ SourceLocation Loc,
+ Sema &Sema) {
+ // C / C++ fields
MemberExpr *ML = dyn_cast<MemberExpr>(LHSExpr);
MemberExpr *MR = dyn_cast<MemberExpr>(RHSExpr);
if (ML && MR && ML->getMemberDecl() == MR->getMemberDecl()) {
if (isa<CXXThisExpr>(ML->getBase()) && isa<CXXThisExpr>(MR->getBase()))
- Sema.Diag(Loc, diag::warn_identity_memvar_assign) << 0;
+ Sema.Diag(Loc, diag::warn_identity_field_assign) << 0;
}
- // Objective-C memvars
+ // Objective-C instance variables
ObjCIvarRefExpr *OL = dyn_cast<ObjCIvarRefExpr>(LHSExpr);
ObjCIvarRefExpr *OR = dyn_cast<ObjCIvarRefExpr>(RHSExpr);
if (OL && OR && OL->getDecl() == OR->getDecl()) {
DeclRefExpr *RL = dyn_cast<DeclRefExpr>(OL->getBase()->IgnoreImpCasts());
DeclRefExpr *RR = dyn_cast<DeclRefExpr>(OR->getBase()->IgnoreImpCasts());
if (RL && RR && RL->getDecl() == RR->getDecl())
- Sema.Diag(Loc, diag::warn_identity_memvar_assign) << 1;
+ Sema.Diag(Loc, diag::warn_identity_field_assign) << 1;
}
}
@@ -7597,7 +7597,7 @@
if (CompoundType.isNull()) {
Expr *RHSCheck = RHS.get();
- CheckIdentityMemvarAssignment(LHSExpr, RHSCheck, Loc, *this);
+ CheckIdentityFieldAssignment(LHSExpr, RHSCheck, Loc, *this);
QualType LHSTy(LHSType);
ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS);
@@ -9350,7 +9350,10 @@
PopExpressionEvaluationContext();
BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back());
-
+
+ if (BSI->HasImplicitReturnType)
+ deduceClosureReturnType(*BSI);
+
PopDeclContext();
QualType RetTy = Context.VoidTy;
@@ -9423,7 +9426,12 @@
BSI->TheDecl->setBody(cast<CompoundStmt>(Body));
- computeNRVO(Body, getCurBlock());
+ // Try to apply the named return value optimization. We have to check again
+ // if we can do this, though, because blocks keep return statements around
+ // to deduce an implicit return type.
+ if (getLangOpts().CPlusPlus && RetTy->isRecordType() &&
+ !BSI->TheDecl->isDependentContext())
+ computeNRVO(Body, getCurBlock());
BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy);
const AnalysisBasedWarnings::Policy &WP = AnalysisWarnings.getDefaultPolicy();
Modified: cfe/branches/tooling/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaLambda.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaLambda.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaLambda.cpp Tue Jul 3 11:18:37 2012
@@ -214,6 +214,141 @@
}
}
+static bool checkReturnValueType(const ASTContext &Ctx, const Expr *E,
+ QualType &DeducedType,
+ QualType &AlternateType) {
+ // Handle ReturnStmts with no expressions.
+ if (!E) {
+ if (AlternateType.isNull())
+ AlternateType = Ctx.VoidTy;
+
+ return Ctx.hasSameType(DeducedType, Ctx.VoidTy);
+ }
+
+ QualType StrictType = E->getType();
+ QualType LooseType = StrictType;
+
+ // In C, enum constants have the type of their underlying integer type,
+ // not the enum. When inferring block return types, we should allow
+ // the enum type if an enum constant is used, unless the enum is
+ // anonymous (in which case there can be no variables of its type).
+ if (!Ctx.getLangOpts().CPlusPlus) {
+ const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts());
+ if (DRE) {
+ const Decl *D = DRE->getDecl();
+ if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
+ const EnumDecl *Enum = cast<EnumDecl>(ECD->getDeclContext());
+ if (Enum->getDeclName() || Enum->getTypedefNameForAnonDecl())
+ LooseType = Ctx.getTypeDeclType(Enum);
+ }
+ }
+ }
+
+ // Special case for the first return statement we find.
+ // The return type has already been tentatively set, but we might still
+ // have an alternate type we should prefer.
+ if (AlternateType.isNull())
+ AlternateType = LooseType;
+
+ if (Ctx.hasSameType(DeducedType, StrictType)) {
+ // FIXME: The loose type is different when there are constants from two
+ // different enums. We could consider warning here.
+ if (AlternateType != Ctx.DependentTy)
+ if (!Ctx.hasSameType(AlternateType, LooseType))
+ AlternateType = Ctx.VoidTy;
+ return true;
+ }
+
+ if (Ctx.hasSameType(DeducedType, LooseType)) {
+ // Use DependentTy to signal that we're using an alternate type and may
+ // need to add casts somewhere.
+ AlternateType = Ctx.DependentTy;
+ return true;
+ }
+
+ if (Ctx.hasSameType(AlternateType, StrictType) ||
+ Ctx.hasSameType(AlternateType, LooseType)) {
+ DeducedType = AlternateType;
+ // Use DependentTy to signal that we're using an alternate type and may
+ // need to add casts somewhere.
+ AlternateType = Ctx.DependentTy;
+ return true;
+ }
+
+ return false;
+}
+
+void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
+ assert(CSI.HasImplicitReturnType);
+
+ // First case: no return statements, implicit void return type.
+ ASTContext &Ctx = getASTContext();
+ if (CSI.Returns.empty()) {
+ // It's possible there were simply no /valid/ return statements.
+ // In this case, the first one we found may have at least given us a type.
+ if (CSI.ReturnType.isNull())
+ CSI.ReturnType = Ctx.VoidTy;
+ return;
+ }
+
+ // Second case: at least one return statement has dependent type.
+ // Delay type checking until instantiation.
+ assert(!CSI.ReturnType.isNull() && "We should have a tentative return type.");
+ if (CSI.ReturnType->isDependentType())
+ return;
+
+ // Third case: only one return statement. Don't bother doing extra work!
+ SmallVectorImpl<ReturnStmt*>::iterator I = CSI.Returns.begin(),
+ E = CSI.Returns.end();
+ if (I+1 == E)
+ return;
+
+ // General case: many return statements.
+ // Check that they all have compatible return types.
+ // For now, that means "identical", with an exception for enum constants.
+ // (In C, enum constants have the type of their underlying integer type,
+ // not the type of the enum. C++ uses the type of the enum.)
+ QualType AlternateType;
+
+ // We require the return types to strictly match here.
+ for (; I != E; ++I) {
+ const ReturnStmt *RS = *I;
+ const Expr *RetE = RS->getRetValue();
+ if (!checkReturnValueType(Ctx, RetE, CSI.ReturnType, AlternateType)) {
+ // FIXME: This is a poor diagnostic for ReturnStmts without expressions.
+ Diag(RS->getLocStart(),
+ diag::err_typecheck_missing_return_type_incompatible)
+ << (RetE ? RetE->getType() : Ctx.VoidTy) << CSI.ReturnType
+ << isa<LambdaScopeInfo>(CSI);
+ // Don't bother fixing up the return statements in the block if some of
+ // them are unfixable anyway.
+ AlternateType = Ctx.VoidTy;
+ // Continue iterating so that we keep emitting diagnostics.
+ }
+ }
+
+ // If our return statements turned out to be compatible, but we needed to
+ // pick a different return type, go through and fix the ones that need it.
+ if (AlternateType == Ctx.DependentTy) {
+ for (SmallVectorImpl<ReturnStmt*>::iterator I = CSI.Returns.begin(),
+ E = CSI.Returns.end();
+ I != E; ++I) {
+ ReturnStmt *RS = *I;
+ Expr *RetE = RS->getRetValue();
+ if (RetE->getType() == CSI.ReturnType)
+ continue;
+
+ // Right now we only support integral fixup casts.
+ assert(CSI.ReturnType->isIntegralOrUnscopedEnumerationType());
+ assert(RetE->getType()->isIntegralOrUnscopedEnumerationType());
+ ExprResult Casted = ImpCastExprToType(RetE, CSI.ReturnType,
+ CK_IntegralCast);
+ assert(Casted.isUsable());
+ RS->setRetValue(Casted.take());
+ }
+ }
+}
+
void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
Declarator &ParamInfo,
Scope *CurScope) {
@@ -659,6 +794,8 @@
// denotes the following type:
// FIXME: Assumes current resolution to core issue 975.
if (LSI->HasImplicitReturnType) {
+ deduceClosureReturnType(*LSI);
+
// - if there are no return statements in the
// compound-statement, or all return statements return
// either an expression of type void or no expression or
Modified: cfe/branches/tooling/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaStmt.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaStmt.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaStmt.cpp Tue Jul 3 11:18:37 2012
@@ -2120,40 +2120,22 @@
// [expr.prim.lambda]p4 in C++11; block literals follow a superset of those
// rules which allows multiple return statements.
CapturingScopeInfo *CurCap = cast<CapturingScopeInfo>(getCurFunction());
+ QualType FnRetType = CurCap->ReturnType;
+
+ // For blocks/lambdas with implicit return types, we check each return
+ // statement individually, and deduce the common return type when the block
+ // or lambda is completed.
if (CurCap->HasImplicitReturnType) {
- QualType ReturnT;
if (RetValExp && !isa<InitListExpr>(RetValExp)) {
ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp);
if (Result.isInvalid())
return StmtError();
RetValExp = Result.take();
- if (!RetValExp->isTypeDependent()) {
- ReturnT = RetValExp->getType();
-
- // In C, enum constants have the type of their underlying integer type,
- // not the enum. When inferring block return values, we should infer
- // the enum type if an enum constant is used, unless the enum is
- // anonymous (in which case there can be no variables of its type).
- if (!getLangOpts().CPlusPlus) {
- Expr *InsideExpr = RetValExp->IgnoreParenImpCasts();
- if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(InsideExpr)) {
- Decl *D = DRE->getDecl();
- if (EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
- EnumDecl *Enum = cast<EnumDecl>(ECD->getDeclContext());
- if (Enum->getDeclName() || Enum->getTypedefNameForAnonDecl()) {
- ReturnT = Context.getTypeDeclType(Enum);
- ExprResult Casted = ImpCastExprToType(RetValExp, ReturnT,
- CK_IntegralCast);
- assert(Casted.isUsable());
- RetValExp = Casted.take();
- }
- }
- }
- }
- } else {
- ReturnT = Context.DependentTy;
- }
+ if (!RetValExp->isTypeDependent())
+ FnRetType = RetValExp->getType();
+ else
+ FnRetType = CurCap->ReturnType = Context.DependentTy;
} else {
if (RetValExp) {
// C++11 [expr.lambda.prim]p4 bans inferring the result from an
@@ -2163,21 +2145,14 @@
<< RetValExp->getSourceRange();
}
- ReturnT = Context.VoidTy;
- }
- // We require the return types to strictly match here.
- if (!CurCap->ReturnType.isNull() &&
- !CurCap->ReturnType->isDependentType() &&
- !ReturnT->isDependentType() &&
- !Context.hasSameType(ReturnT, CurCap->ReturnType)) {
- Diag(ReturnLoc, diag::err_typecheck_missing_return_type_incompatible)
- << ReturnT << CurCap->ReturnType
- << (getCurLambda() != 0);
- return StmtError();
+ FnRetType = Context.VoidTy;
}
- CurCap->ReturnType = ReturnT;
+
+ // Although we'll properly infer the type of the block once it's completed,
+ // make sure we provide a return type now for better error recovery.
+ if (CurCap->ReturnType.isNull())
+ CurCap->ReturnType = FnRetType;
}
- QualType FnRetType = CurCap->ReturnType;
assert(!FnRetType.isNull());
if (BlockScopeInfo *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) {
@@ -2245,10 +2220,12 @@
ReturnStmt *Result = new (Context) ReturnStmt(ReturnLoc, RetValExp,
NRVOCandidate);
- // If we need to check for the named return value optimization, save the
- // return statement in our scope for later processing.
- if (getLangOpts().CPlusPlus && FnRetType->isRecordType() &&
- !CurContext->isDependentContext())
+ // If we need to check for the named return value optimization,
+ // or if we need to infer the return type,
+ // save the return statement in our scope for later processing.
+ if (CurCap->HasImplicitReturnType ||
+ (getLangOpts().CPlusPlus && FnRetType->isRecordType() &&
+ !CurContext->isDependentContext()))
FunctionScopes.back()->Returns.push_back(Result);
return Owned(Result);
Modified: cfe/branches/tooling/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaTemplateInstantiate.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaTemplateInstantiate.cpp Tue Jul 3 11:18:37 2012
@@ -1832,8 +1832,6 @@
const MultiLevelTemplateArgumentList &TemplateArgs,
TemplateSpecializationKind TSK,
bool Complain) {
- bool Invalid = false;
-
CXXRecordDecl *PatternDef
= cast_or_null<CXXRecordDecl>(Pattern->getDefinition());
if (DiagnoseUninstantiableTemplate(*this, PointOfInstantiation, Instantiation,
@@ -1879,7 +1877,7 @@
// Do substitution on the base class specifiers.
if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs))
- Invalid = true;
+ Instantiation->setInvalidDecl();
TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs);
SmallVector<Decl*, 4> Fields;
@@ -1905,7 +1903,7 @@
continue;
if ((*Member)->isInvalidDecl()) {
- Invalid = true;
+ Instantiation->setInvalidDecl();
continue;
}
@@ -1932,11 +1930,12 @@
}
if (NewMember->isInvalidDecl())
- Invalid = true;
+ Instantiation->setInvalidDecl();
} else {
// FIXME: Eventually, a NULL return will mean that one of the
- // instantiations was a semantic disaster, and we'll want to set Invalid =
- // true. For now, we expect to skip some members that we can't yet handle.
+ // instantiations was a semantic disaster, and we'll want to mark the
+ // declaration invalid.
+ // For now, we expect to skip some members that we can't yet handle.
}
}
@@ -1995,9 +1994,7 @@
Instantiation->setRBraceLoc(Pattern->getRBraceLoc());
}
- if (Instantiation->isInvalidDecl())
- Invalid = true;
- else {
+ if (!Instantiation->isInvalidDecl()) {
// Instantiate any out-of-line class template partial
// specializations now.
for (TemplateDeclInstantiator::delayed_partial_spec_iterator
@@ -2007,7 +2004,7 @@
if (!Instantiator.InstantiateClassTemplatePartialSpecialization(
P->first,
P->second)) {
- Invalid = true;
+ Instantiation->setInvalidDecl();
break;
}
}
@@ -2016,7 +2013,7 @@
// Exit the scope of this instantiation.
SavedContext.pop();
- if (!Invalid) {
+ if (!Instantiation->isInvalidDecl()) {
Consumer.HandleTagDeclDefinition(Instantiation);
// Always emit the vtable for an explicit instantiation definition
@@ -2025,7 +2022,7 @@
MarkVTableUsed(PointOfInstantiation, Instantiation, true);
}
- return Invalid;
+ return Instantiation->isInvalidDecl();
}
/// \brief Instantiate the definition of an enum from a given pattern.
Modified: cfe/branches/tooling/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTReader.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTReader.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTReader.cpp Tue Jul 3 11:18:37 2012
@@ -4673,7 +4673,9 @@
unsigned Index = ID - NUM_PREDEF_DECL_IDS;
if (Index >= DeclsLoaded.size()) {
+ assert(0 && "declaration ID out-of-range for AST file");
Error("declaration ID out-of-range for AST file");
+ return 0;
}
if (!DeclsLoaded[Index]) {
Modified: cfe/branches/tooling/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTWriter.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTWriter.cpp Tue Jul 3 11:18:37 2012
@@ -3140,7 +3140,8 @@
ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
: Stream(Stream), Context(0), PP(0), Chain(0), WritingModule(0),
- WritingAST(false), ASTHasCompilerErrors(false),
+ WritingAST(false), DoneWritingDeclsAndTypes(false),
+ ASTHasCompilerErrors(false),
FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID),
FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID),
@@ -3400,7 +3401,15 @@
Record.push_back(reinterpret_cast<uint64_t>(NS));
}
}
-
+
+ // Make sure visible decls, added to DeclContexts previously loaded from
+ // an AST file, are registered for serialization.
+ for (SmallVector<const Decl *, 16>::iterator
+ I = UpdatingVisibleDecls.begin(),
+ E = UpdatingVisibleDecls.end(); I != E; ++I) {
+ GetDeclRef(*I);
+ }
+
// Resolve any declaration pointers within the declaration updates block.
ResolveDeclUpdatesBlocks();
@@ -3433,6 +3442,8 @@
}
Stream.ExitBlock();
+ DoneWritingDeclsAndTypes = true;
+
WriteFileDeclIDsMap();
WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
WriteComments();
@@ -3819,6 +3830,11 @@
TypeIdx &Idx = TypeIdxs[T];
if (Idx.getIndex() == 0) {
+ if (DoneWritingDeclsAndTypes) {
+ assert(0 && "New type seen after serializing all the types to emit!");
+ return TypeIdx();
+ }
+
// We haven't seen this type before. Assign it a new ID and put it
// into the queue of types to emit.
Idx = TypeIdx(NextTypeID++);
@@ -3856,6 +3872,11 @@
assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer");
DeclID &ID = DeclIDs[D];
if (ID == 0) {
+ if (DoneWritingDeclsAndTypes) {
+ assert(0 && "New decl seen after serializing all the decls to emit!");
+ return 0;
+ }
+
// We haven't seen this declaration before. Give it a new ID and
// enqueue it in the list of declarations to emit.
ID = NextDeclID++;
@@ -4477,6 +4498,7 @@
return; // Not a source decl added to a DeclContext from PCH.
AddUpdatedDeclContext(DC);
+ UpdatingVisibleDecls.push_back(D);
}
void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp Tue Jul 3 11:18:37 2012
@@ -15,6 +15,7 @@
#include "ClangSACheckers.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -23,40 +24,32 @@
namespace {
class AttrNonNullChecker
- : public Checker< check::PreStmt<CallExpr> > {
+ : public Checker< check::PreCall > {
mutable OwningPtr<BugType> BT;
public:
- void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
+ void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
};
} // end anonymous namespace
-void AttrNonNullChecker::checkPreStmt(const CallExpr *CE,
+void AttrNonNullChecker::checkPreCall(const CallEvent &Call,
CheckerContext &C) const {
- ProgramStateRef state = C.getState();
- const LocationContext *LCtx = C.getLocationContext();
-
- // Check if the callee has a 'nonnull' attribute.
- SVal X = state->getSVal(CE->getCallee(), LCtx);
-
- const FunctionDecl *FD = X.getAsFunctionDecl();
+ const Decl *FD = Call.getDecl();
if (!FD)
return;
- const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
+ const NonNullAttr *Att = FD->getAttr<NonNullAttr>();
if (!Att)
return;
- // Iterate through the arguments of CE and check them for null.
- unsigned idx = 0;
-
- for (CallExpr::const_arg_iterator I=CE->arg_begin(), E=CE->arg_end(); I!=E;
- ++I, ++idx) {
+ ProgramStateRef state = C.getState();
+ // Iterate through the arguments of CE and check them for null.
+ for (unsigned idx = 0, count = Call.getNumArgs(); idx != count; ++idx) {
if (!Att->isNonNull(idx))
continue;
- SVal V = state->getSVal(*I, LCtx);
+ SVal V = Call.getArgSVal(idx);
DefinedSVal *DV = dyn_cast<DefinedSVal>(&V);
// If the value is unknown or undefined, we can't perform this check.
@@ -65,11 +58,16 @@
if (!isa<Loc>(*DV)) {
// If the argument is a union type, we want to handle a potential
- // transparent_unoin GCC extension.
- QualType T = (*I)->getType();
+ // transparent_union GCC extension.
+ const Expr *ArgE = Call.getArgExpr(idx);
+ if (!ArgE)
+ continue;
+
+ QualType T = ArgE->getType();
const RecordType *UT = T->getAsUnionType();
if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
continue;
+
if (nonloc::CompoundVal *CSV = dyn_cast<nonloc::CompoundVal>(DV)) {
nonloc::CompoundVal::iterator CSV_I = CSV->begin();
assert(CSV_I != CSV->end());
@@ -78,8 +76,7 @@
assert(++CSV_I == CSV->end());
if (!DV)
continue;
- }
- else {
+ } else {
// FIXME: Handle LazyCompoundVals?
continue;
}
@@ -106,10 +103,10 @@
"'nonnull' parameter", errorNode);
// Highlight the range of the argument that was null.
- const Expr *arg = *I;
- R->addRange(arg->getSourceRange());
- R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(errorNode,
- arg, R));
+ R->addRange(Call.getArgSourceRange(idx));
+ if (const Expr *ArgE = Call.getArgExpr(idx))
+ R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(errorNode,
+ ArgE, R));
// Emit the bug report.
C.EmitReport(R);
}
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp Tue Jul 3 11:18:37 2012
@@ -17,10 +17,10 @@
#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
@@ -46,10 +46,10 @@
// Utility functions.
//===----------------------------------------------------------------------===//
-static const char* GetReceiverNameType(const ObjCMessage &msg) {
+static StringRef GetReceiverInterfaceName(const ObjCMethodCall &msg) {
if (const ObjCInterfaceDecl *ID = msg.getReceiverInterface())
- return ID->getIdentifier()->getNameStart();
- return 0;
+ return ID->getIdentifier()->getName();
+ return StringRef();
}
enum FoundationClass {
@@ -95,15 +95,15 @@
mutable OwningPtr<APIMisuse> BT;
void WarnNilArg(CheckerContext &C,
- const ObjCMessage &msg, unsigned Arg) const;
+ const ObjCMethodCall &msg, unsigned Arg) const;
public:
- void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;
+ void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
};
}
void NilArgChecker::WarnNilArg(CheckerContext &C,
- const ObjCMessage &msg,
+ const ObjCMethodCall &msg,
unsigned int Arg) const
{
if (!BT)
@@ -112,7 +112,7 @@
if (ExplodedNode *N = C.generateSink()) {
SmallString<128> sbuf;
llvm::raw_svector_ostream os(sbuf);
- os << "Argument to '" << GetReceiverNameType(msg) << "' method '"
+ os << "Argument to '" << GetReceiverInterfaceName(msg) << "' method '"
<< msg.getSelector().getAsString() << "' cannot be nil";
BugReport *R = new BugReport(*BT, os.str(), N);
@@ -121,7 +121,7 @@
}
}
-void NilArgChecker::checkPreObjCMessage(ObjCMessage msg,
+void NilArgChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
CheckerContext &C) const {
const ObjCInterfaceDecl *ID = msg.getReceiverInterface();
if (!ID)
@@ -151,7 +151,7 @@
Name == "compare:options:range:locale:" ||
Name == "componentsSeparatedByCharactersInSet:" ||
Name == "initWithFormat:") {
- if (isNil(msg.getArgSVal(0, C.getLocationContext(), C.getState())))
+ if (isNil(msg.getArgSVal(0)))
WarnNilArg(C, msg, 0);
}
}
@@ -455,11 +455,11 @@
mutable OwningPtr<BugType> BT;
public:
- void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;
+ void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
};
}
-void ClassReleaseChecker::checkPreObjCMessage(ObjCMessage msg,
+void ClassReleaseChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
CheckerContext &C) const {
if (!BT) {
@@ -511,18 +511,18 @@
mutable Selector initWithObjectsAndKeysS;
mutable OwningPtr<BugType> BT;
- bool isVariadicMessage(const ObjCMessage &msg) const;
+ bool isVariadicMessage(const ObjCMethodCall &msg) const;
public:
- void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;
+ void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
};
}
/// isVariadicMessage - Returns whether the given message is a variadic message,
/// where all arguments must be Objective-C types.
bool
-VariadicMethodTypeChecker::isVariadicMessage(const ObjCMessage &msg) const {
- const ObjCMethodDecl *MD = msg.getMethodDecl();
+VariadicMethodTypeChecker::isVariadicMessage(const ObjCMethodCall &msg) const {
+ const ObjCMethodDecl *MD = msg.getDecl();
if (!MD || !MD->isVariadic() || isa<ObjCProtocolDecl>(MD->getDeclContext()))
return false;
@@ -566,7 +566,7 @@
}
}
-void VariadicMethodTypeChecker::checkPreObjCMessage(ObjCMessage msg,
+void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
CheckerContext &C) const {
if (!BT) {
BT.reset(new APIMisuse("Arguments passed to variadic method aren't all "
@@ -602,7 +602,7 @@
ProgramStateRef state = C.getState();
for (unsigned I = variadicArgsBegin; I != variadicArgsEnd; ++I) {
- QualType ArgTy = msg.getArgType(I);
+ QualType ArgTy = msg.getArgExpr(I)->getType();
if (ArgTy->isObjCObjectPointerType())
continue;
@@ -611,8 +611,7 @@
continue;
// Ignore pointer constants.
- if (isa<loc::ConcreteInt>(msg.getArgSVal(I, C.getLocationContext(),
- state)))
+ if (isa<loc::ConcreteInt>(msg.getArgSVal(I)))
continue;
// Ignore pointer types annotated with 'NSObject' attribute.
@@ -624,9 +623,8 @@
continue;
// Generate only one error node to use for all bug reports.
- if (!errorNode.hasValue()) {
+ if (!errorNode.hasValue())
errorNode = C.addTransition();
- }
if (!errorNode.getValue())
continue;
@@ -634,17 +632,18 @@
SmallString<128> sbuf;
llvm::raw_svector_ostream os(sbuf);
- if (const char *TypeName = GetReceiverNameType(msg))
+ StringRef TypeName = GetReceiverInterfaceName(msg);
+ if (!TypeName.empty())
os << "Argument to '" << TypeName << "' method '";
else
os << "Argument to method '";
os << msg.getSelector().getAsString()
- << "' should be an Objective-C pointer type, not '"
- << ArgTy.getAsString() << "'";
+ << "' should be an Objective-C pointer type, not '";
+ ArgTy.print(os, C.getLangOpts());
+ os << "'";
- BugReport *R = new BugReport(*BT, os.str(),
- errorNode.getValue());
+ BugReport *R = new BugReport(*BT, os.str(), errorNode.getValue());
R->addRange(msg.getArgSourceRange(I));
C.EmitReport(R);
}
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CStringChecker.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Tue Jul 3 11:18:37 2012
@@ -66,7 +66,7 @@
const StoreManager::InvalidatedSymbols *,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call) const;
+ const CallEvent *Call) const;
typedef void (CStringChecker::*FnCheck)(CheckerContext &,
const CallExpr *) const;
@@ -1895,7 +1895,7 @@
const StoreManager::InvalidatedSymbols *,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call) const {
+ const CallEvent *Call) const {
CStringLength::EntryMap Entries = state->get<CStringLength>();
if (Entries.isEmpty())
return state;
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp Tue Jul 3 11:18:37 2012
@@ -15,8 +15,8 @@
#include "ClangSACheckers.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/AST/ParentMap.h"
#include "clang/Basic/TargetInfo.h"
@@ -27,7 +27,8 @@
namespace {
class CallAndMessageChecker
- : public Checker< check::PreStmt<CallExpr>, check::PreObjCMessage > {
+ : public Checker< check::PreStmt<CallExpr>, check::PreObjCMessage,
+ check::PreCall > {
mutable OwningPtr<BugType> BT_call_null;
mutable OwningPtr<BugType> BT_call_undef;
mutable OwningPtr<BugType> BT_call_arg;
@@ -38,24 +39,22 @@
public:
void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
- void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;
+ void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
+ void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
private:
- static void PreVisitProcessArgs(CheckerContext &C,CallOrObjCMessage callOrMsg,
- const char *BT_desc, OwningPtr<BugType> &BT);
- static bool PreVisitProcessArg(CheckerContext &C, SVal V,SourceRange argRange,
- const Expr *argEx,
+ static bool PreVisitProcessArg(CheckerContext &C, SVal V,
+ SourceRange argRange, const Expr *argEx,
const bool checkUninitFields,
- const char *BT_desc,
- OwningPtr<BugType> &BT);
+ const char *BT_desc, OwningPtr<BugType> &BT);
static void EmitBadCall(BugType *BT, CheckerContext &C, const CallExpr *CE);
- void emitNilReceiverBug(CheckerContext &C, const ObjCMessage &msg,
+ void emitNilReceiverBug(CheckerContext &C, const ObjCMethodCall &msg,
ExplodedNode *N) const;
void HandleNilReceiver(CheckerContext &C,
ProgramStateRef state,
- ObjCMessage msg) const;
+ const ObjCMethodCall &msg) const;
static void LazyInit_BT(const char *desc, OwningPtr<BugType> &BT) {
if (!BT)
@@ -76,27 +75,6 @@
C.EmitReport(R);
}
-void CallAndMessageChecker::PreVisitProcessArgs(CheckerContext &C,
- CallOrObjCMessage callOrMsg,
- const char *BT_desc,
- OwningPtr<BugType> &BT) {
- // Don't check for uninitialized field values in arguments if the
- // caller has a body that is available and we have the chance to inline it.
- // This is a hack, but is a reasonable compromise betweens sometimes warning
- // and sometimes not depending on if we decide to inline a function.
- const Decl *D = callOrMsg.getDecl();
- const bool checkUninitFields =
- !(C.getAnalysisManager().shouldInlineCall() &&
- (D && D->getBody()));
-
- for (unsigned i = 0, e = callOrMsg.getNumArgs(); i != e; ++i)
- if (PreVisitProcessArg(C, callOrMsg.getArgSVal(i),
- callOrMsg.getArgSourceRange(i), callOrMsg.getArg(i),
- checkUninitFields,
- BT_desc, BT))
- return;
-}
-
bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
SVal V, SourceRange argRange,
const Expr *argEx,
@@ -105,10 +83,10 @@
OwningPtr<BugType> &BT) {
if (V.isUndef()) {
if (ExplodedNode *N = C.generateSink()) {
- LazyInit_BT(BT_desc, BT);
+ LazyInit_BT("Uninitialized argument value", BT);
// Generate a report for this bug.
- BugReport *R = new BugReport(*BT, BT->getName(), N);
+ BugReport *R = new BugReport(*BT, BT_desc, N);
R->addRange(argRange);
if (argEx)
R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, argEx,
@@ -210,8 +188,9 @@
CheckerContext &C) const{
const Expr *Callee = CE->getCallee()->IgnoreParens();
+ ProgramStateRef State = C.getState();
const LocationContext *LCtx = C.getLocationContext();
- SVal L = C.getState()->getSVal(Callee, LCtx);
+ SVal L = State->getSVal(Callee, LCtx);
if (L.isUndef()) {
if (!BT_call_undef)
@@ -221,76 +200,101 @@
return;
}
- if (isa<loc::ConcreteInt>(L)) {
+ if (L.isZeroConstant()) {
if (!BT_call_null)
BT_call_null.reset(
new BuiltinBug("Called function pointer is null (null dereference)"));
EmitBadCall(BT_call_null.get(), C, CE);
}
+}
+
+void CallAndMessageChecker::checkPreCall(const CallEvent &Call,
+ CheckerContext &C) const {
+ // Don't check for uninitialized field values in arguments if the
+ // caller has a body that is available and we have the chance to inline it.
+ // This is a hack, but is a reasonable compromise betweens sometimes warning
+ // and sometimes not depending on if we decide to inline a function.
+ const Decl *D = Call.getDecl();
+ const bool checkUninitFields =
+ !(C.getAnalysisManager().shouldInlineCall() &&
+ (D && D->getBody()));
+
+ OwningPtr<BugType> *BT;
+ const char *Desc;
- PreVisitProcessArgs(C, CallOrObjCMessage(CE, C.getState(), LCtx),
- "Function call argument is an uninitialized value",
- BT_call_arg);
+ switch (Call.getKind()) {
+ case CE_ObjCPropertyAccess:
+ BT = &BT_msg_arg;
+ // Getters do not have arguments, so we don't need to worry about this.
+ Desc = "Argument for property setter is an uninitialized value";
+ break;
+ case CE_ObjCMessage:
+ BT = &BT_msg_arg;
+ Desc = "Argument in message expression is an uninitialized value";
+ break;
+ case CE_Block:
+ BT = &BT_call_arg;
+ Desc = "Block call argument is an uninitialized value";
+ break;
+ default:
+ BT = &BT_call_arg;
+ Desc = "Function call argument is an uninitialized value";
+ break;
+ }
+
+ for (unsigned i = 0, e = Call.getNumArgs(); i != e; ++i)
+ if (PreVisitProcessArg(C, Call.getArgSVal(i),
+ Call.getArgSourceRange(i), Call.getArgExpr(i),
+ checkUninitFields, Desc, *BT))
+ return;
}
-void CallAndMessageChecker::checkPreObjCMessage(ObjCMessage msg,
+void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
CheckerContext &C) const {
+ SVal recVal = msg.getReceiverSVal();
+ if (recVal.isUndef()) {
+ if (ExplodedNode *N = C.generateSink()) {
+ BugType *BT = 0;
+ if (isa<ObjCPropertyAccess>(msg)) {
+ if (!BT_objc_prop_undef)
+ BT_objc_prop_undef.reset(new BuiltinBug("Property access on an "
+ "uninitialized object pointer"));
+ BT = BT_objc_prop_undef.get();
+ } else {
+ if (!BT_msg_undef)
+ BT_msg_undef.reset(new BuiltinBug("Receiver in message expression "
+ "is an uninitialized value"));
+ BT = BT_msg_undef.get();
+ }
+ BugReport *R = new BugReport(*BT, BT->getName(), N);
+ R->addRange(msg.getReceiverSourceRange());
- ProgramStateRef state = C.getState();
- const LocationContext *LCtx = C.getLocationContext();
-
- // FIXME: Handle 'super'?
- if (const Expr *receiver = msg.getInstanceReceiver()) {
- SVal recVal = state->getSVal(receiver, LCtx);
- if (recVal.isUndef()) {
- if (ExplodedNode *N = C.generateSink()) {
- BugType *BT = 0;
- if (msg.isPureMessageExpr()) {
- if (!BT_msg_undef)
- BT_msg_undef.reset(new BuiltinBug("Receiver in message expression "
- "is an uninitialized value"));
- BT = BT_msg_undef.get();
- }
- else {
- if (!BT_objc_prop_undef)
- BT_objc_prop_undef.reset(new BuiltinBug("Property access on an "
- "uninitialized object pointer"));
- BT = BT_objc_prop_undef.get();
- }
- BugReport *R =
- new BugReport(*BT, BT->getName(), N);
- R->addRange(receiver->getSourceRange());
+ // FIXME: getTrackNullOrUndefValueVisitor can't handle "super" yet.
+ if (const Expr *ReceiverE = msg.getInstanceReceiverExpr())
R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
- receiver,
+ ReceiverE,
R));
- C.EmitReport(R);
- }
+ C.EmitReport(R);
+ }
+ return;
+ } else {
+ // Bifurcate the state into nil and non-nil ones.
+ DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
+
+ ProgramStateRef state = C.getState();
+ ProgramStateRef notNilState, nilState;
+ llvm::tie(notNilState, nilState) = state->assume(receiverVal);
+
+ // Handle receiver must be nil.
+ if (nilState && !notNilState) {
+ HandleNilReceiver(C, state, msg);
return;
- } else {
- // Bifurcate the state into nil and non-nil ones.
- DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
-
- ProgramStateRef notNilState, nilState;
- llvm::tie(notNilState, nilState) = state->assume(receiverVal);
-
- // Handle receiver must be nil.
- if (nilState && !notNilState) {
- HandleNilReceiver(C, state, msg);
- return;
- }
}
}
-
- const char *bugDesc = msg.isPropertySetter() ?
- "Argument for property setter is an uninitialized value"
- : "Argument in message expression is an uninitialized value";
- // Check for any arguments that are uninitialized/undefined.
- PreVisitProcessArgs(C, CallOrObjCMessage(msg, state, LCtx),
- bugDesc, BT_msg_arg);
}
void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C,
- const ObjCMessage &msg,
+ const ObjCMethodCall &msg,
ExplodedNode *N) const {
if (!BT_msg_ret)
@@ -301,12 +305,14 @@
SmallString<200> buf;
llvm::raw_svector_ostream os(buf);
os << "The receiver of message '" << msg.getSelector().getAsString()
- << "' is nil and returns a value of type '"
- << msg.getType(C.getASTContext()).getAsString() << "' that will be garbage";
+ << "' is nil and returns a value of type '";
+ msg.getResultType().print(os, C.getLangOpts());
+ os << "' that will be garbage";
BugReport *report = new BugReport(*BT_msg_ret, os.str(), N);
- if (const Expr *receiver = msg.getInstanceReceiver()) {
- report->addRange(receiver->getSourceRange());
+ report->addRange(msg.getReceiverSourceRange());
+ // FIXME: This won't track "self" in messages to super.
+ if (const Expr *receiver = msg.getInstanceReceiverExpr()) {
report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
receiver,
report));
@@ -322,25 +328,25 @@
void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
ProgramStateRef state,
- ObjCMessage msg) const {
+ const ObjCMethodCall &Msg) const {
ASTContext &Ctx = C.getASTContext();
// Check the return type of the message expression. A message to nil will
// return different values depending on the return type and the architecture.
- QualType RetTy = msg.getType(Ctx);
+ QualType RetTy = Msg.getResultType();
CanQualType CanRetTy = Ctx.getCanonicalType(RetTy);
const LocationContext *LCtx = C.getLocationContext();
if (CanRetTy->isStructureOrClassType()) {
// Structure returns are safe since the compiler zeroes them out.
- SVal V = C.getSValBuilder().makeZeroVal(msg.getType(Ctx));
- C.addTransition(state->BindExpr(msg.getMessageExpr(), LCtx, V));
+ SVal V = C.getSValBuilder().makeZeroVal(RetTy);
+ C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V));
return;
}
// Other cases: check if sizeof(return type) > sizeof(void*)
if (CanRetTy != Ctx.VoidTy && C.getLocationContext()->getParentMap()
- .isConsumedExpr(msg.getMessageExpr())) {
+ .isConsumedExpr(Msg.getOriginExpr())) {
// Compute: sizeof(void *) and sizeof(return type)
const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy);
@@ -353,7 +359,7 @@
Ctx.LongLongTy == CanRetTy ||
Ctx.UnsignedLongLongTy == CanRetTy))) {
if (ExplodedNode *N = C.generateSink(state))
- emitNilReceiverBug(C, msg, N);
+ emitNilReceiverBug(C, Msg, N);
return;
}
@@ -370,8 +376,8 @@
// it most likely isn't nil. We should assume the semantics
// of this case unless we have *a lot* more knowledge.
//
- SVal V = C.getSValBuilder().makeZeroVal(msg.getType(Ctx));
- C.addTransition(state->BindExpr(msg.getMessageExpr(), LCtx, V));
+ SVal V = C.getSValBuilder().makeZeroVal(RetTy);
+ C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V));
return;
}
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp Tue Jul 3 11:18:37 2012
@@ -37,6 +37,8 @@
check::PostStmt<CallExpr>,
check::PreObjCMessage,
check::PostObjCMessage,
+ check::PreCall,
+ check::PostCall,
check::BranchCondition,
check::Location,
check::Bind,
@@ -72,14 +74,42 @@
/// which does not include the control flow statements such as IfStmt. The
/// callback can be specialized to be called with any subclass of Stmt.
///
- /// check::PostStmt<DeclStmt>
+ /// check::PostStmt<CallExpr>
void checkPostStmt(const CallExpr *DS, CheckerContext &C) const;
- /// \brief Pre-visit the Objective C messages.
- void checkPreObjCMessage(const ObjCMessage &Msg, CheckerContext &C) const {}
+ /// \brief Pre-visit the Objective C message.
+ ///
+ /// This will be called before the analyzer core processes the method call.
+ /// This is called for any action which produces an Objective-C message send,
+ /// including explicit message syntax and property access. See the subclasses
+ /// of ObjCMethodCall for more details.
+ ///
+ /// check::PreObjCMessage
+ void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const {}
- /// \brief Post-visit the Objective C messages.
- void checkPostObjCMessage(const ObjCMessage &Msg, CheckerContext &C) const {}
+ /// \brief Post-visit the Objective C message.
+ /// \sa checkPreObjCMessage()
+ ///
+ /// check::PostObjCMessage
+ void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const {}
+
+ /// \brief Pre-visit an abstract "call" event.
+ ///
+ /// This is used for checkers that want to check arguments or attributed
+ /// behavior for functions and methods no matter how they are being invoked.
+ ///
+ /// Note that this includes ALL cross-body invocations, so if you want to
+ /// limit your checks to, say, function calls, you can either test for that
+ /// or fall back to the explicit callback (i.e. check::PreStmt).
+ ///
+ /// check::PreCall
+ void checkPreCall(const CallEvent &Call, CheckerContext &C) const {}
+
+ /// \brief Post-visit an abstract "call" event.
+ /// \sa checkPreObjCMessage()
+ ///
+ /// check::PostCall
+ void checkPostCall(const CallEvent &Call, CheckerContext &C) const {}
/// \brief Pre-visit of the condition statement of a branch (such as IfStmt).
void checkBranchCondition(const Stmt *Condition, CheckerContext &Ctx) const {}
@@ -206,7 +236,7 @@
const StoreManager::InvalidatedSymbols *Invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call) const {
+ const CallEvent *Call) const {
return State;
}
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Tue Jul 3 11:18:37 2012
@@ -18,7 +18,7 @@
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
@@ -124,7 +124,7 @@
void checkPreStmt(const CallExpr *S, CheckerContext &C) const;
void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
- void checkPreObjCMessage(const ObjCMessage &Msg, CheckerContext &C) const;
+ void checkPreObjCMessage(const ObjCMethodCall &Call, CheckerContext &C) const;
void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
void checkEndPath(CheckerContext &C) const;
@@ -140,7 +140,7 @@
const StoreManager::InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call) const;
+ const CallEvent *Call) const;
bool wantsRegionChangeUpdate(ProgramStateRef state) const {
return true;
}
@@ -200,7 +200,7 @@
/// Check if the function is not known to us. So, for example, we could
/// conservatively assume it can free/reallocate it's pointer arguments.
- bool doesNotFreeMemory(const CallOrObjCMessage *Call,
+ bool doesNotFreeMemory(const CallEvent *Call,
ProgramStateRef State) const;
static bool SummarizeValue(raw_ostream &os, SVal V);
@@ -481,7 +481,8 @@
C.addTransition(State);
}
-static bool isFreeWhenDoneSetToZero(CallOrObjCMessage Call, Selector &S) {
+static bool isFreeWhenDoneSetToZero(const ObjCMethodCall &Call) {
+ Selector S = Call.getSelector();
for (unsigned i = 1; i < S.getNumArgs(); ++i)
if (S.getNameForSlot(i).equals("freeWhenDone"))
if (Call.getArgSVal(i).isConstant(0))
@@ -490,27 +491,21 @@
return false;
}
-void MallocChecker::checkPreObjCMessage(const ObjCMessage &Msg,
- CheckerContext &C) const {
- const ObjCMethodDecl *MD = Msg.getMethodDecl();
- if (!MD)
- return;
-
- CallOrObjCMessage Call(Msg, C.getState(), C.getLocationContext());
- Selector S = Msg.getSelector();
-
+void MallocChecker::checkPreObjCMessage(const ObjCMethodCall &Call,
+ CheckerContext &C) const {
// If the first selector is dataWithBytesNoCopy, assume that the memory will
// be released with 'free' by the new object.
// Ex: [NSData dataWithBytesNoCopy:bytes length:10];
// Unless 'freeWhenDone' param set to 0.
// TODO: Check that the memory was allocated with malloc.
+ Selector S = Call.getSelector();
if ((S.getNameForSlot(0) == "dataWithBytesNoCopy" ||
S.getNameForSlot(0) == "initWithBytesNoCopy" ||
S.getNameForSlot(0) == "initWithCharactersNoCopy") &&
- !isFreeWhenDoneSetToZero(Call, S)){
+ !isFreeWhenDoneSetToZero(Call)){
unsigned int argIdx = 0;
- C.addTransition(FreeMemAux(C, Call.getArg(argIdx),
- Msg.getMessageExpr(), C.getState(), true));
+ C.addTransition(FreeMemAux(C, Call.getArgExpr(argIdx),
+ Call.getOriginExpr(), C.getState(), true));
}
}
@@ -1310,130 +1305,30 @@
}
// Check if the function is known to us. So, for example, we could
-// conservatively assume it can free/reallocate it's pointer arguments.
+// conservatively assume it can free/reallocate its pointer arguments.
// (We assume that the pointers cannot escape through calls to system
// functions not handled by this checker.)
-bool MallocChecker::doesNotFreeMemory(const CallOrObjCMessage *Call,
+bool MallocChecker::doesNotFreeMemory(const CallEvent *Call,
ProgramStateRef State) const {
- if (!Call)
- return false;
+ assert(Call);
// For now, assume that any C++ call can free memory.
// TODO: If we want to be more optimistic here, we'll need to make sure that
// regions escape to C++ containers. They seem to do that even now, but for
// mysterious reasons.
- if (Call->isCXXCall())
- return false;
-
- const Decl *D = Call->getDecl();
- if (!D)
- return false;
-
- ASTContext &ASTC = State->getStateManager().getContext();
-
- // If it's one of the allocation functions we can reason about, we model
- // its behavior explicitly.
- if (isa<FunctionDecl>(D) && isMemFunction(cast<FunctionDecl>(D), ASTC)) {
- return true;
- }
-
- // If it's not a system call, assume it frees memory.
- if (!Call->isInSystemHeader())
+ if (!(isa<FunctionCall>(Call) || isa<ObjCMethodCall>(Call)))
return false;
- // Process C/ObjC functions.
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- // White list the system functions whose arguments escape.
- const IdentifierInfo *II = FD->getIdentifier();
- if (!II)
- return true;
- StringRef FName = II->getName();
-
- // White list thread local storage.
- if (FName.equals("pthread_setspecific"))
- return false;
-
- // White list xpc connection context.
- // TODO: Ensure that the deallocation actually happens, need to reason
- // about "xpc_connection_set_finalizer_f".
- if (FName.equals("xpc_connection_set_context"))
- return false;
-
- // White list the 'XXXNoCopy' ObjC functions.
- if (FName.endswith("NoCopy")) {
- // Look for the deallocator argument. We know that the memory ownership
- // is not transferred only if the deallocator argument is
- // 'kCFAllocatorNull'.
- for (unsigned i = 1; i < Call->getNumArgs(); ++i) {
- const Expr *ArgE = Call->getArg(i)->IgnoreParenCasts();
- if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) {
- StringRef DeallocatorName = DE->getFoundDecl()->getName();
- if (DeallocatorName == "kCFAllocatorNull")
- return true;
- }
- }
- return false;
- }
-
- // PR12101
- // Many CoreFoundation and CoreGraphics might allow a tracked object
- // to escape.
- if (Call->isCFCGAllowingEscape(FName))
- return false;
-
- // Associating streams with malloced buffers. The pointer can escape if
- // 'closefn' is specified (and if that function does free memory).
- // Currently, we do not inspect the 'closefn' function (PR12101).
- if (FName == "funopen")
- if (Call->getNumArgs() >= 4 && !Call->getArgSVal(4).isConstant(0))
- return false;
-
- // Do not warn on pointers passed to 'setbuf' when used with std streams,
- // these leaks might be intentional when setting the buffer for stdio.
- // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer
- if (FName == "setbuf" || FName =="setbuffer" ||
- FName == "setlinebuf" || FName == "setvbuf") {
- if (Call->getNumArgs() >= 1)
- if (const DeclRefExpr *Arg =
- dyn_cast<DeclRefExpr>(Call->getArg(0)->IgnoreParenCasts()))
- if (const VarDecl *D = dyn_cast<VarDecl>(Arg->getDecl()))
- if (D->getCanonicalDecl()->getName().find("std")
- != StringRef::npos)
- return false;
- }
-
- // A bunch of other functions which either take ownership of a pointer or
- // wrap the result up in a struct or object, meaning it can be freed later.
- // (See RetainCountChecker.) Not all the parameters here are invalidated,
- // but the Malloc checker cannot differentiate between them. The right way
- // of doing this would be to implement a pointer escapes callback.
- if (FName == "CGBitmapContextCreate" ||
- FName == "CGBitmapContextCreateWithData" ||
- FName == "CVPixelBufferCreateWithBytes" ||
- FName == "CVPixelBufferCreateWithPlanarBytes" ||
- FName == "OSAtomicEnqueue") {
- return false;
- }
-
- // Whitelist NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
- // be deallocated by NSMapRemove.
- if (FName.startswith("NS") && (FName.find("Insert") != StringRef::npos))
- return false;
-
- // If the call has a callback as an argument, assume the memory
- // can be freed.
- if (Call->hasNonZeroCallbackArg())
+ // Check Objective-C messages by selector name.
+ if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
+ // If it's not a framework call, or if it takes a callback, assume it
+ // can free memory.
+ if (!Call->isInSystemHeader() || Call->hasNonZeroCallbackArg())
return false;
- // Otherwise, assume that the function does not free memory.
- // Most system calls, do not free the memory.
- return true;
-
- // Process ObjC functions.
- } else if (const ObjCMethodDecl * ObjCD = dyn_cast<ObjCMethodDecl>(D)) {
- Selector S = ObjCD->getSelector();
+ Selector S = Msg->getSelector();
- // White list the ObjC functions which do free memory.
+ // Whitelist the ObjC methods which do free memory.
// - Anything containing 'freeWhenDone' param set to 1.
// Ex: dataWithBytesNoCopy:length:freeWhenDone.
for (unsigned i = 1; i < S.getNumArgs(); ++i) {
@@ -1448,33 +1343,109 @@
// If the first selector ends with NoCopy, assume that the ownership is
// transferred as well.
// Ex: [NSData dataWithBytesNoCopy:bytes length:10];
- if (S.getNameForSlot(0).endswith("NoCopy")) {
+ StringRef FirstSlot = S.getNameForSlot(0);
+ if (FirstSlot.endswith("NoCopy"))
return false;
- }
// If the first selector starts with addPointer, insertPointer,
// or replacePointer, assume we are dealing with NSPointerArray or similar.
// This is similar to C++ containers (vector); we still might want to check
- // that the pointers get freed, by following the container itself.
- if (S.getNameForSlot(0).startswith("addPointer") ||
- S.getNameForSlot(0).startswith("insertPointer") ||
- S.getNameForSlot(0).startswith("replacePointer")) {
+ // that the pointers get freed by following the container itself.
+ if (FirstSlot.startswith("addPointer") ||
+ FirstSlot.startswith("insertPointer") ||
+ FirstSlot.startswith("replacePointer")) {
return false;
}
- // If the call has a callback as an argument, assume the memory
- // can be freed.
- if (Call->hasNonZeroCallbackArg())
- return false;
+ // Otherwise, assume that the method does not free memory.
+ // Most framework methods do not free memory.
+ return true;
+ }
+
+ // At this point the only thing left to handle is straight function calls.
+ const FunctionDecl *FD = cast<FunctionCall>(Call)->getDecl();
+ if (!FD)
+ return false;
- // Otherwise, assume that the function does not free memory.
- // Most system calls, do not free the memory.
+ ASTContext &ASTC = State->getStateManager().getContext();
+
+ // If it's one of the allocation functions we can reason about, we model
+ // its behavior explicitly.
+ if (isMemFunction(FD, ASTC))
return true;
+
+ // If it's not a system call, assume it frees memory.
+ if (!Call->isInSystemHeader())
+ return false;
+
+ // White list the system functions whose arguments escape.
+ const IdentifierInfo *II = FD->getIdentifier();
+ if (!II)
+ return false;
+ StringRef FName = II->getName();
+
+ // White list the 'XXXNoCopy' CoreFoundation functions.
+ // We specifically check these before
+ if (FName.endswith("NoCopy")) {
+ // Look for the deallocator argument. We know that the memory ownership
+ // is not transferred only if the deallocator argument is
+ // 'kCFAllocatorNull'.
+ for (unsigned i = 1; i < Call->getNumArgs(); ++i) {
+ const Expr *ArgE = Call->getArgExpr(i)->IgnoreParenCasts();
+ if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) {
+ StringRef DeallocatorName = DE->getFoundDecl()->getName();
+ if (DeallocatorName == "kCFAllocatorNull")
+ return true;
+ }
+ }
+ return false;
}
- // Otherwise, assume that the function can free memory.
- return false;
+ // Associating streams with malloced buffers. The pointer can escape if
+ // 'closefn' is specified (and if that function does free memory),
+ // but it will not if closefn is not specified.
+ // Currently, we do not inspect the 'closefn' function (PR12101).
+ if (FName == "funopen")
+ if (Call->getNumArgs() >= 4 && Call->getArgSVal(4).isConstant(0))
+ return true;
+ // Do not warn on pointers passed to 'setbuf' when used with std streams,
+ // these leaks might be intentional when setting the buffer for stdio.
+ // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer
+ if (FName == "setbuf" || FName =="setbuffer" ||
+ FName == "setlinebuf" || FName == "setvbuf") {
+ if (Call->getNumArgs() >= 1) {
+ const Expr *ArgE = Call->getArgExpr(0)->IgnoreParenCasts();
+ if (const DeclRefExpr *ArgDRE = dyn_cast<DeclRefExpr>(ArgE))
+ if (const VarDecl *D = dyn_cast<VarDecl>(ArgDRE->getDecl()))
+ if (D->getCanonicalDecl()->getName().find("std") != StringRef::npos)
+ return false;
+ }
+ }
+
+ // A bunch of other functions which either take ownership of a pointer or
+ // wrap the result up in a struct or object, meaning it can be freed later.
+ // (See RetainCountChecker.) Not all the parameters here are invalidated,
+ // but the Malloc checker cannot differentiate between them. The right way
+ // of doing this would be to implement a pointer escapes callback.
+ if (FName == "CGBitmapContextCreate" ||
+ FName == "CGBitmapContextCreateWithData" ||
+ FName == "CVPixelBufferCreateWithBytes" ||
+ FName == "CVPixelBufferCreateWithPlanarBytes" ||
+ FName == "OSAtomicEnqueue") {
+ return false;
+ }
+
+ // Handle cases where we know a buffer's /address/ can escape.
+ // Note that the above checks handle some special cases where we know that
+ // even though the address escapes, it's still our responsibility to free the
+ // buffer.
+ if (Call->argumentsMayEscape())
+ return false;
+
+ // Otherwise, assume that the function does not free memory.
+ // Most system calls do not free the memory.
+ return true;
}
// If the symbol we are tracking is invalidated, but not explicitly (ex: the &p
@@ -1485,7 +1456,7 @@
const StoreManager::InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call) const {
+ const CallEvent *Call) const {
if (!invalidated || invalidated->empty())
return State;
llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp Tue Jul 3 11:18:37 2012
@@ -20,9 +20,9 @@
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Decl.h"
@@ -36,29 +36,20 @@
mutable Selector releaseS;
public:
- void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;
+ void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
};
} // end anonymous namespace
-void NSAutoreleasePoolChecker::checkPreObjCMessage(ObjCMessage msg,
+void NSAutoreleasePoolChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
CheckerContext &C) const {
-
- const Expr *receiver = msg.getInstanceReceiver();
- if (!receiver)
+ if (!msg.isInstanceMessage())
return;
-
- // FIXME: Enhance with value-tracking information instead of consulting
- // the type of the expression.
- const ObjCObjectPointerType* PT =
- receiver->getType()->getAs<ObjCObjectPointerType>();
-
- if (!PT)
- return;
- const ObjCInterfaceDecl *OD = PT->getInterfaceDecl();
+
+ const ObjCInterfaceDecl *OD = msg.getReceiverInterface();
if (!OD)
return;
- if (!OD->getIdentifier()->getName().equals("NSAutoreleasePool"))
+ if (!OD->getIdentifier()->isStr("NSAutoreleasePool"))
return;
if (releaseS.isNull())
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp Tue Jul 3 11:18:37 2012
@@ -15,8 +15,8 @@
#include "ClangSACheckers.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
#include "llvm/ADT/StringSwitch.h"
#include <cstdarg>
@@ -29,7 +29,7 @@
check::PostObjCMessage > {
public:
void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
- void checkPostObjCMessage(const ObjCMessage &msg, CheckerContext &C) const;
+ void checkPostObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
};
}
@@ -98,7 +98,7 @@
return (Arg == NULL);
}
-void NoReturnFunctionChecker::checkPostObjCMessage(const ObjCMessage &Msg,
+void NoReturnFunctionChecker::checkPostObjCMessage(const ObjCMethodCall &Msg,
CheckerContext &C) const {
// HACK: This entire check is to handle two messages in the Cocoa frameworks:
// -[NSAssertionHandler
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp Tue Jul 3 11:18:37 2012
@@ -21,7 +21,6 @@
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/AST/ParentMap.h"
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp Tue Jul 3 11:18:37 2012
@@ -39,9 +39,9 @@
#include "ClangSACheckers.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/AST/ParentMap.h"
@@ -50,31 +50,27 @@
static bool shouldRunOnFunctionOrMethod(const NamedDecl *ND);
static bool isInitializationMethod(const ObjCMethodDecl *MD);
-static bool isInitMessage(const ObjCMessage &msg);
+static bool isInitMessage(const ObjCMethodCall &Msg);
static bool isSelfVar(SVal location, CheckerContext &C);
namespace {
-class ObjCSelfInitChecker : public Checker< check::PreObjCMessage,
- check::PostObjCMessage,
+class ObjCSelfInitChecker : public Checker< check::PostObjCMessage,
check::PostStmt<ObjCIvarRefExpr>,
check::PreStmt<ReturnStmt>,
- check::PreStmt<CallExpr>,
- check::PostStmt<CallExpr>,
+ check::PreCall,
+ check::PostCall,
check::Location,
check::Bind > {
public:
- void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;
- void checkPostObjCMessage(ObjCMessage msg, CheckerContext &C) const;
+ void checkPostObjCMessage(const ObjCMethodCall &Msg, CheckerContext &C) const;
void checkPostStmt(const ObjCIvarRefExpr *E, CheckerContext &C) const;
void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
- void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
- void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
void checkLocation(SVal location, bool isLoad, const Stmt *S,
CheckerContext &C) const;
void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const;
- void checkPreStmt(const CallOrObjCMessage &CE, CheckerContext &C) const;
- void checkPostStmt(const CallOrObjCMessage &CE, CheckerContext &C) const;
+ void checkPreCall(const CallEvent &CE, CheckerContext &C) const;
+ void checkPostCall(const CallEvent &CE, CheckerContext &C) const;
};
} // end anonymous namespace
@@ -183,7 +179,7 @@
C.EmitReport(report);
}
-void ObjCSelfInitChecker::checkPostObjCMessage(ObjCMessage msg,
+void ObjCSelfInitChecker::checkPostObjCMessage(const ObjCMethodCall &Msg,
CheckerContext &C) const {
// When encountering a message that does initialization (init rule),
// tag the return value so that we know later on that if self has this value
@@ -194,7 +190,7 @@
C.getCurrentAnalysisDeclContext()->getDecl())))
return;
- if (isInitMessage(msg)) {
+ if (isInitMessage(Msg)) {
// Tag the return value as the result of an initializer.
ProgramStateRef state = C.getState();
@@ -203,14 +199,11 @@
// value out when we return from this method.
state = state->set<CalledInit>(true);
- SVal V = state->getSVal(msg.getMessageExpr(), C.getLocationContext());
+ SVal V = state->getSVal(Msg.getOriginExpr(), C.getLocationContext());
addSelfFlag(state, V, SelfFlag_InitRes, C);
return;
}
- CallOrObjCMessage MsgWrapper(msg, C.getState(), C.getLocationContext());
- checkPostStmt(MsgWrapper, C);
-
// We don't check for an invalid 'self' in an obj-c message expression to cut
// down false positives where logging functions get information from self
// (like its class) or doing "invalidation" on self when the initialization
@@ -241,8 +234,8 @@
"'[(super or self) init...]'");
}
-// When a call receives a reference to 'self', [Pre/Post]VisitGenericCall pass
-// the SelfFlags from the object 'self' point to before the call, to the new
+// When a call receives a reference to 'self', [Pre/Post]Call pass
+// the SelfFlags from the object 'self' points to before the call to the new
// object after the call. This is to avoid invalidation of 'self' by logging
// functions.
// Another common pattern in classes with multiple initializers is to put the
@@ -257,26 +250,13 @@
// Until we can use inter-procedural analysis, in such a call, transfer the
// SelfFlags to the result of the call.
-void ObjCSelfInitChecker::checkPreStmt(const CallExpr *CE,
+void ObjCSelfInitChecker::checkPreCall(const CallEvent &CE,
CheckerContext &C) const {
- CallOrObjCMessage CEWrapper(CE, C.getState(), C.getLocationContext());
- checkPreStmt(CEWrapper, C);
-}
-
-void ObjCSelfInitChecker::checkPostStmt(const CallExpr *CE,
- CheckerContext &C) const {
- CallOrObjCMessage CEWrapper(CE, C.getState(), C.getLocationContext());
- checkPostStmt(CEWrapper, C);
-}
-
-void ObjCSelfInitChecker::checkPreObjCMessage(ObjCMessage Msg,
- CheckerContext &C) const {
- CallOrObjCMessage MsgWrapper(Msg, C.getState(), C.getLocationContext());
- checkPreStmt(MsgWrapper, C);
-}
+ // FIXME: A callback should disable checkers at the start of functions.
+ if (!shouldRunOnFunctionOrMethod(dyn_cast<NamedDecl>(
+ C.getCurrentAnalysisDeclContext()->getDecl())))
+ return;
-void ObjCSelfInitChecker::checkPreStmt(const CallOrObjCMessage &CE,
- CheckerContext &C) const {
ProgramStateRef state = C.getState();
unsigned NumArgs = CE.getNumArgs();
// If we passed 'self' as and argument to the call, record it in the state
@@ -298,9 +278,19 @@
}
}
-void ObjCSelfInitChecker::checkPostStmt(const CallOrObjCMessage &CE,
+void ObjCSelfInitChecker::checkPostCall(const CallEvent &CE,
CheckerContext &C) const {
+ // FIXME: A callback should disable checkers at the start of functions.
+ if (!shouldRunOnFunctionOrMethod(dyn_cast<NamedDecl>(
+ C.getCurrentAnalysisDeclContext()->getDecl())))
+ return;
+
ProgramStateRef state = C.getState();
+ SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>();
+ if (!prevFlags)
+ return;
+ state = state->remove<PreCallSelfFlags>();
+
unsigned NumArgs = CE.getNumArgs();
for (unsigned i = 0; i < NumArgs; ++i) {
SVal argV = CE.getArgSVal(i);
@@ -308,8 +298,6 @@
// If the address of 'self' is being passed to the call, assume that the
// 'self' after the call will have the same flags.
// EX: log(&self)
- SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>();
- state = state->remove<PreCallSelfFlags>();
addSelfFlag(state, state->getSVal(cast<Loc>(argV)), prevFlags, C);
return;
} else if (hasSelfFlag(argV, SelfFlag_Self, C)) {
@@ -317,8 +305,6 @@
// returns 'self'. So assign the flags, which were set on 'self' to the
// return value.
// EX: self = performMoreInitialization(self)
- SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>();
- state = state->remove<PreCallSelfFlags>();
const Expr *CallExpr = CE.getOriginExpr();
if (CallExpr)
addSelfFlag(state, state->getSVal(CallExpr, C.getLocationContext()),
@@ -407,8 +393,8 @@
return MD->getMethodFamily() == OMF_init;
}
-static bool isInitMessage(const ObjCMessage &msg) {
- return msg.getMethodFamily() == OMF_init;
+static bool isInitMessage(const ObjCMethodCall &Call) {
+ return Call.getMethodFamily() == OMF_init;
}
//===----------------------------------------------------------------------===//
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Tue Jul 3 11:18:37 2012
@@ -23,10 +23,10 @@
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableList.h"
@@ -66,6 +66,7 @@
/// particular argument.
enum ArgEffect { DoNothing, Autorelease, Dealloc, DecRef, DecRefMsg,
DecRefBridgedTransfered,
+ DecRefAndStopTracking, DecRefMsgAndStopTracking,
IncRefMsg, IncRef, MakeCollectable, MayEscape,
NewAutoreleasePool, StopTracking };
@@ -431,6 +432,12 @@
bool isSimple() const {
return Args.isEmpty();
}
+
+private:
+ ArgEffects getArgEffects() const { return Args; }
+ ArgEffect getDefaultArgEffect() const { return DefaultArgEffect; }
+
+ friend class RetainSummaryManager;
};
} // end anonymous namespace
@@ -449,9 +456,6 @@
ObjCSummaryKey(const ObjCInterfaceDecl *d, Selector s)
: II(d ? d->getIdentifier() : 0), S(s) {}
- ObjCSummaryKey(const ObjCInterfaceDecl *d, IdentifierInfo *ii, Selector s)
- : II(d ? d->getIdentifier() : ii), S(s) {}
-
ObjCSummaryKey(Selector s)
: II(0), S(s) {}
@@ -495,21 +499,16 @@
public:
ObjCSummaryCache() {}
- const RetainSummary * find(const ObjCInterfaceDecl *D, IdentifierInfo *ClsName,
- Selector S) {
- // Lookup the method using the decl for the class @interface. If we
- // have no decl, lookup using the class name.
- return D ? find(D, S) : find(ClsName, S);
- }
-
const RetainSummary * find(const ObjCInterfaceDecl *D, Selector S) {
// Do a lookup with the (D,S) pair. If we find a match return
// the iterator.
ObjCSummaryKey K(D, S);
MapTy::iterator I = M.find(K);
- if (I != M.end() || !D)
+ if (I != M.end())
return I->second;
+ if (!D)
+ return NULL;
// Walk the super chain. If we find a hit with a parent, we'll end
// up returning that summary. We actually allow that key (null,S), as
@@ -625,9 +624,6 @@
ArgEffects getArgEffects();
enum UnaryFuncKind { cfretain, cfrelease, cfmakecollectable };
-
-public:
- RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
const RetainSummary *getUnarySummary(const FunctionType* FT,
UnaryFuncKind func);
@@ -740,42 +736,32 @@
InitializeMethodSummaries();
}
- const RetainSummary *getSummary(const FunctionDecl *FD,
- const CallOrObjCMessage *CME = 0);
+ const RetainSummary *getSummary(const CallEvent &Call,
+ ProgramStateRef State = 0);
+
+ const RetainSummary *getFunctionSummary(const FunctionDecl *FD);
- const RetainSummary *getMethodSummary(Selector S, IdentifierInfo *ClsName,
- const ObjCInterfaceDecl *ID,
+ const RetainSummary *getMethodSummary(Selector S, const ObjCInterfaceDecl *ID,
const ObjCMethodDecl *MD,
QualType RetTy,
ObjCMethodSummariesTy &CachedSummaries);
- const RetainSummary *getInstanceMethodSummary(const ObjCMessage &msg,
- ProgramStateRef state,
- const LocationContext *LC);
-
- const RetainSummary *getInstanceMethodSummary(const ObjCMessage &msg,
- const ObjCInterfaceDecl *ID) {
- return getMethodSummary(msg.getSelector(), 0, ID, msg.getMethodDecl(),
- msg.getType(Ctx), ObjCMethodSummaries);
- }
-
- const RetainSummary *getClassMethodSummary(const ObjCMessage &msg) {
- const ObjCInterfaceDecl *Class = 0;
- if (!msg.isInstanceMessage())
- Class = msg.getReceiverInterface();
-
- return getMethodSummary(msg.getSelector(), Class->getIdentifier(),
- Class, msg.getMethodDecl(), msg.getType(Ctx),
- ObjCClassMethodSummaries);
+ const RetainSummary *getInstanceMethodSummary(const ObjCMethodCall &M,
+ ProgramStateRef State);
+
+ const RetainSummary *getClassMethodSummary(const ObjCMethodCall &M) {
+ assert(!M.isInstanceMessage());
+ const ObjCInterfaceDecl *Class = M.getReceiverInterface();
+
+ return getMethodSummary(M.getSelector(), Class, M.getDecl(),
+ M.getResultType(), ObjCClassMethodSummaries);
}
/// getMethodSummary - This version of getMethodSummary is used to query
/// the summary for the current method being analyzed.
const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD) {
- // FIXME: Eventually this should be unneeded.
const ObjCInterfaceDecl *ID = MD->getClassInterface();
Selector S = MD->getSelector();
- IdentifierInfo *ClsName = ID->getIdentifier();
QualType ResultTy = MD->getResultType();
ObjCMethodSummariesTy *CachedSummaries;
@@ -784,11 +770,11 @@
else
CachedSummaries = &ObjCClassMethodSummaries;
- return getMethodSummary(S, ClsName, ID, MD, ResultTy, *CachedSummaries);
+ return getMethodSummary(S, ID, MD, ResultTy, *CachedSummaries);
}
const RetainSummary *getStandardMethodSummary(const ObjCMethodDecl *MD,
- Selector S, QualType RetTy);
+ Selector S, QualType RetTy);
void updateSummaryFromAnnotations(const RetainSummary *&Summ,
const ObjCMethodDecl *MD);
@@ -796,11 +782,18 @@
void updateSummaryFromAnnotations(const RetainSummary *&Summ,
const FunctionDecl *FD);
+ void updateSummaryForCall(const RetainSummary *&Summ,
+ const CallEvent &Call);
+
bool isGCEnabled() const { return GCEnabled; }
bool isARCEnabled() const { return ARCEnabled; }
bool isARCorGCEnabled() const { return GCEnabled || ARCEnabled; }
+
+ RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
+
+ friend class RetainSummaryTemplate;
};
// Used to avoid allocating long-term (BPAlloc'd) memory for default retain
@@ -813,10 +806,8 @@
RetainSummary ScratchSummary;
bool Accessed;
public:
- RetainSummaryTemplate(const RetainSummary *&real, const RetainSummary &base,
- RetainSummaryManager &mgr)
- : Manager(mgr), RealSummary(real), ScratchSummary(real ? *real : base),
- Accessed(false) {}
+ RetainSummaryTemplate(const RetainSummary *&real, RetainSummaryManager &mgr)
+ : Manager(mgr), RealSummary(real), ScratchSummary(*real), Accessed(false) {}
~RetainSummaryTemplate() {
if (Accessed)
@@ -888,9 +879,100 @@
return FName.find("MakeCollectable") != StringRef::npos;
}
+static ArgEffect getStopTrackingEquivalent(ArgEffect E) {
+ switch (E) {
+ case DoNothing:
+ case Autorelease:
+ case DecRefBridgedTransfered:
+ case IncRef:
+ case IncRefMsg:
+ case MakeCollectable:
+ case MayEscape:
+ case NewAutoreleasePool:
+ case StopTracking:
+ return StopTracking;
+ case DecRef:
+ case DecRefAndStopTracking:
+ return DecRefAndStopTracking;
+ case DecRefMsg:
+ case DecRefMsgAndStopTracking:
+ return DecRefMsgAndStopTracking;
+ case Dealloc:
+ return Dealloc;
+ }
+
+ llvm_unreachable("Unknown ArgEffect kind");
+}
+
+void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S,
+ const CallEvent &Call) {
+ if (Call.hasNonZeroCallbackArg()) {
+ ArgEffect RecEffect = getStopTrackingEquivalent(S->getReceiverEffect());
+ ArgEffect DefEffect = getStopTrackingEquivalent(S->getDefaultArgEffect());
+
+ ArgEffects CustomArgEffects = S->getArgEffects();
+ for (ArgEffects::iterator I = CustomArgEffects.begin(),
+ E = CustomArgEffects.end();
+ I != E; ++I) {
+ ArgEffect Translated = getStopTrackingEquivalent(I->second);
+ if (Translated != DefEffect)
+ ScratchArgs = AF.add(ScratchArgs, I->first, Translated);
+ }
+
+ RetEffect RE = RetEffect::MakeNoRet();
+
+ // Special cases where the callback argument CANNOT free the return value.
+ // This can generally only happen if we know that the callback will only be
+ // called when the return value is already being deallocated.
+ if (const FunctionCall *FC = dyn_cast<FunctionCall>(&Call)) {
+ IdentifierInfo *Name = FC->getDecl()->getIdentifier();
+
+ // This callback frees the associated buffer.
+ if (Name->isStr("CGBitmapContextCreateWithData"))
+ RE = S->getRetEffect();
+ }
+
+ S = getPersistentSummary(RE, RecEffect, DefEffect);
+ }
+}
+
const RetainSummary *
-RetainSummaryManager::getSummary(const FunctionDecl *FD,
- const CallOrObjCMessage *CME) {
+RetainSummaryManager::getSummary(const CallEvent &Call,
+ ProgramStateRef State) {
+ const RetainSummary *Summ;
+ switch (Call.getKind()) {
+ case CE_Function:
+ Summ = getFunctionSummary(cast<FunctionCall>(Call).getDecl());
+ break;
+ case CE_CXXMember:
+ case CE_Block:
+ case CE_CXXConstructor:
+ case CE_CXXAllocator:
+ // FIXME: These calls are currently unsupported.
+ return getPersistentStopSummary();
+ case CE_ObjCMessage:
+ case CE_ObjCPropertyAccess: {
+ const ObjCMethodCall &Msg = cast<ObjCMethodCall>(Call);
+ if (Msg.isInstanceMessage())
+ Summ = getInstanceMethodSummary(Msg, State);
+ else
+ Summ = getClassMethodSummary(Msg);
+ break;
+ }
+ }
+
+ updateSummaryForCall(Summ, Call);
+
+ assert(Summ && "Unknown call type?");
+ return Summ;
+}
+
+const RetainSummary *
+RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) {
+ // If we don't know what function we're calling, use our default summary.
+ if (!FD)
+ return getDefaultSummary();
+
// Look up a summary in our cache of FunctionDecls -> Summaries.
FuncSummariesTy::iterator I = FuncSummaries.find(FD);
if (I != FuncSummaries.end())
@@ -905,13 +987,6 @@
S = getPersistentStopSummary();
break;
}
- // For C++ methods, generate an implicit "stop" summary as well. We
- // can relax this once we have a clear policy for C++ methods and
- // ownership attributes.
- if (isa<CXXMethodDecl>(FD)) {
- S = getPersistentStopSummary();
- break;
- }
// [PR 3337] Use 'getAs<FunctionType>' to strip away any typedefs on the
// function's type.
@@ -1007,9 +1082,6 @@
ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);
ScratchArgs = AF.add(ScratchArgs, 2, StopTracking);
S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
- } else if (CME && CME->hasNonZeroCallbackArg()) {
- // Allow objects to escape through callbacks. radar://10973977
- S = getPersistentStopSummary();
}
// Did we get a summary?
@@ -1100,6 +1172,10 @@
}
while (0);
+ // If we got all the way here without any luck, use a default summary.
+ if (!S)
+ S = getDefaultSummary();
+
// Annotations override defaults.
updateSummaryFromAnnotations(S, FD);
@@ -1162,7 +1238,8 @@
if (!FD)
return;
- RetainSummaryTemplate Template(Summ, *getDefaultSummary(), *this);
+ assert(Summ && "Must have a summary to add annotations to.");
+ RetainSummaryTemplate Template(Summ, *this);
// Effects on the parameters.
unsigned parm_idx = 0;
@@ -1210,7 +1287,8 @@
if (!MD)
return;
- RetainSummaryTemplate Template(Summ, *getDefaultSummary(), *this);
+ assert(Summ && "Must have a valid summary to add annotations to");
+ RetainSummaryTemplate Template(Summ, *this);
bool isTrackedLoc = false;
// Effects on the receiver.
@@ -1370,56 +1448,46 @@
}
const RetainSummary *
-RetainSummaryManager::getInstanceMethodSummary(const ObjCMessage &msg,
- ProgramStateRef state,
- const LocationContext *LC) {
-
- // We need the type-information of the tracked receiver object
- // Retrieve it from the state.
- const Expr *Receiver = msg.getInstanceReceiver();
- const ObjCInterfaceDecl *ID = 0;
-
- // FIXME: Is this really working as expected? There are cases where
- // we just use the 'ID' from the message expression.
- SVal receiverV;
-
- if (Receiver) {
- receiverV = state->getSValAsScalarOrLoc(Receiver, LC);
-
- // FIXME: Eventually replace the use of state->get<RefBindings> with
- // a generic API for reasoning about the Objective-C types of symbolic
- // objects.
- if (SymbolRef Sym = receiverV.getAsLocSymbol())
- if (const RefVal *T = state->get<RefBindings>(Sym))
- if (const ObjCObjectPointerType* PT =
+RetainSummaryManager::getInstanceMethodSummary(const ObjCMethodCall &Msg,
+ ProgramStateRef State) {
+ const ObjCInterfaceDecl *ReceiverClass = 0;
+
+ // We do better tracking of the type of the object than the core ExprEngine.
+ // See if we have its type in our private state.
+ // FIXME: Eventually replace the use of state->get<RefBindings> with
+ // a generic API for reasoning about the Objective-C types of symbolic
+ // objects.
+ SVal ReceiverV = Msg.getReceiverSVal();
+ if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
+ if (const RefVal *T = State->get<RefBindings>(Sym))
+ if (const ObjCObjectPointerType *PT =
T->getType()->getAs<ObjCObjectPointerType>())
- ID = PT->getInterfaceDecl();
+ ReceiverClass = PT->getInterfaceDecl();
- // FIXME: this is a hack. This may or may not be the actual method
- // that is called.
- if (!ID) {
- if (const ObjCObjectPointerType *PT =
- Receiver->getType()->getAs<ObjCObjectPointerType>())
- ID = PT->getInterfaceDecl();
- }
- } else {
- // FIXME: Hack for 'super'.
- ID = msg.getReceiverInterface();
- }
+ // If we don't know what kind of object this is, fall back to its static type.
+ if (!ReceiverClass)
+ ReceiverClass = Msg.getReceiverInterface();
// FIXME: The receiver could be a reference to a class, meaning that
// we should use the class method.
- return getInstanceMethodSummary(msg, ID);
+ // id x = [NSObject class];
+ // [x performSelector:... withObject:... afterDelay:...];
+ Selector S = Msg.getSelector();
+ const ObjCMethodDecl *Method = Msg.getDecl();
+ if (!Method && ReceiverClass)
+ Method = ReceiverClass->getInstanceMethod(S);
+
+ return getMethodSummary(S, ReceiverClass, Method, Msg.getResultType(),
+ ObjCMethodSummaries);
}
const RetainSummary *
-RetainSummaryManager::getMethodSummary(Selector S, IdentifierInfo *ClsName,
- const ObjCInterfaceDecl *ID,
+RetainSummaryManager::getMethodSummary(Selector S, const ObjCInterfaceDecl *ID,
const ObjCMethodDecl *MD, QualType RetTy,
ObjCMethodSummariesTy &CachedSummaries) {
// Look up a summary in our summary cache.
- const RetainSummary *Summ = CachedSummaries.find(ID, ClsName, S);
+ const RetainSummary *Summ = CachedSummaries.find(ID, S);
if (!Summ) {
Summ = getStandardMethodSummary(MD, S, RetTy);
@@ -1428,7 +1496,7 @@
updateSummaryFromAnnotations(Summ, MD);
// Memoize the summary.
- CachedSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
+ CachedSummaries[ObjCSummaryKey(ID, S)] = Summ;
}
return Summ;
@@ -1445,29 +1513,6 @@
addClassMethSummary("NSAutoreleasePool", "addObject",
getPersistentSummary(RetEffect::MakeNoRet(),
DoNothing, Autorelease));
-
- // Create the summaries for [NSObject performSelector...]. We treat
- // these as 'stop tracking' for the arguments because they are often
- // used for delegates that can release the object. When we have better
- // inter-procedural analysis we can potentially do something better. This
- // workaround is to remove false positives.
- const RetainSummary *Summ =
- getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, StopTracking);
- IdentifierInfo *NSObjectII = &Ctx.Idents.get("NSObject");
- addClsMethSummary(NSObjectII, Summ, "performSelector", "withObject",
- "afterDelay", NULL);
- addClsMethSummary(NSObjectII, Summ, "performSelector", "withObject",
- "afterDelay", "inModes", NULL);
- addClsMethSummary(NSObjectII, Summ, "performSelectorOnMainThread",
- "withObject", "waitUntilDone", NULL);
- addClsMethSummary(NSObjectII, Summ, "performSelectorOnMainThread",
- "withObject", "waitUntilDone", "modes", NULL);
- addClsMethSummary(NSObjectII, Summ, "performSelector", "onThread",
- "withObject", "waitUntilDone", NULL);
- addClsMethSummary(NSObjectII, Summ, "performSelector", "onThread",
- "withObject", "waitUntilDone", "modes", NULL);
- addClsMethSummary(NSObjectII, Summ, "performSelectorInBackground",
- "withObject", NULL);
}
void RetainSummaryManager::InitializeMethodSummaries() {
@@ -2335,12 +2380,10 @@
check::EndPath,
check::PostStmt<BlockExpr>,
check::PostStmt<CastExpr>,
- check::PostStmt<CallExpr>,
- check::PostStmt<CXXConstructExpr>,
check::PostStmt<ObjCArrayLiteral>,
check::PostStmt<ObjCDictionaryLiteral>,
check::PostStmt<ObjCBoxedExpr>,
- check::PostObjCMessage,
+ check::PostCall,
check::PreStmt<ReturnStmt>,
check::RegionChanges,
eval::Assume,
@@ -2479,15 +2522,13 @@
void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
void checkPostStmt(const CastExpr *CE, CheckerContext &C) const;
- void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
- void checkPostStmt(const CXXConstructExpr *CE, CheckerContext &C) const;
void checkPostStmt(const ObjCArrayLiteral *AL, CheckerContext &C) const;
void checkPostStmt(const ObjCDictionaryLiteral *DL, CheckerContext &C) const;
void checkPostStmt(const ObjCBoxedExpr *BE, CheckerContext &C) const;
- void checkPostObjCMessage(const ObjCMessage &Msg, CheckerContext &C) const;
+ void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
- void checkSummary(const RetainSummary &Summ, const CallOrObjCMessage &Call,
+ void checkSummary(const RetainSummary &Summ, const CallEvent &Call,
CheckerContext &C) const;
bool evalCall(const CallExpr *CE, CheckerContext &C) const;
@@ -2500,7 +2541,7 @@
const StoreManager::InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call) const;
+ const CallEvent *Call) const;
bool wantsRegionChangeUpdate(ProgramStateRef state) const {
return true;
@@ -2641,58 +2682,6 @@
C.addTransition(state);
}
-void RetainCountChecker::checkPostStmt(const CallExpr *CE,
- CheckerContext &C) const {
- if (C.wasInlined)
- return;
-
- // Get the callee.
- ProgramStateRef state = C.getState();
- const Expr *Callee = CE->getCallee();
- SVal L = state->getSVal(Callee, C.getLocationContext());
-
- RetainSummaryManager &Summaries = getSummaryManager(C);
- const RetainSummary *Summ = 0;
-
- // FIXME: Better support for blocks. For now we stop tracking anything
- // that is passed to blocks.
- // FIXME: Need to handle variables that are "captured" by the block.
- if (dyn_cast_or_null<BlockDataRegion>(L.getAsRegion())) {
- Summ = Summaries.getPersistentStopSummary();
- } else if (const FunctionDecl *FD = L.getAsFunctionDecl()) {
- CallOrObjCMessage CME(CE, state, C.getLocationContext());
- Summ = Summaries.getSummary(FD, &CME);
- } else if (const CXXMemberCallExpr *me = dyn_cast<CXXMemberCallExpr>(CE)) {
- if (const CXXMethodDecl *MD = me->getMethodDecl()) {
- CallOrObjCMessage CME(CE, state, C.getLocationContext());
- Summ = Summaries.getSummary(MD, &CME);
- }
- }
-
- if (!Summ)
- Summ = Summaries.getDefaultSummary();
-
- checkSummary(*Summ, CallOrObjCMessage(CE, state, C.getLocationContext()), C);
-}
-
-void RetainCountChecker::checkPostStmt(const CXXConstructExpr *CE,
- CheckerContext &C) const {
- const CXXConstructorDecl *Ctor = CE->getConstructor();
- if (!Ctor)
- return;
-
- RetainSummaryManager &Summaries = getSummaryManager(C);
- ProgramStateRef state = C.getState();
- CallOrObjCMessage CME(CE, state, C.getLocationContext());
- const RetainSummary *Summ = Summaries.getSummary(Ctor, &CME);
-
- // If we didn't get a summary, this constructor doesn't affect retain counts.
- if (!Summ)
- return;
-
- checkSummary(*Summ, CallOrObjCMessage(CE, state, C.getLocationContext()), C);
-}
-
void RetainCountChecker::processObjCLiterals(CheckerContext &C,
const Expr *Ex) const {
ProgramStateRef state = C.getState();
@@ -2751,25 +2740,14 @@
C.addTransition(State);
}
-void RetainCountChecker::checkPostObjCMessage(const ObjCMessage &Msg,
- CheckerContext &C) const {
- ProgramStateRef state = C.getState();
-
- RetainSummaryManager &Summaries = getSummaryManager(C);
-
- const RetainSummary *Summ;
- if (Msg.isInstanceMessage()) {
- const LocationContext *LC = C.getLocationContext();
- Summ = Summaries.getInstanceMethodSummary(Msg, state, LC);
- } else {
- Summ = Summaries.getClassMethodSummary(Msg);
- }
-
- // If we didn't get a summary, this message doesn't affect retain counts.
- if (!Summ)
+void RetainCountChecker::checkPostCall(const CallEvent &Call,
+ CheckerContext &C) const {
+ if (C.wasInlined)
return;
- checkSummary(*Summ, CallOrObjCMessage(Msg, state, C.getLocationContext()), C);
+ RetainSummaryManager &Summaries = getSummaryManager(C);
+ const RetainSummary *Summ = Summaries.getSummary(Call, C.getState());
+ checkSummary(*Summ, Call, C);
}
/// GetReturnType - Used to get the return type of a message expression or
@@ -2801,7 +2779,7 @@
}
void RetainCountChecker::checkSummary(const RetainSummary &Summ,
- const CallOrObjCMessage &CallOrMsg,
+ const CallEvent &CallOrMsg,
CheckerContext &C) const {
ProgramStateRef state = C.getState();
@@ -2827,17 +2805,18 @@
// Evaluate the effect on the message receiver.
bool ReceiverIsTracked = false;
- if (!hasErr && CallOrMsg.isObjCMessage()) {
- const LocationContext *LC = C.getLocationContext();
- SVal Receiver = CallOrMsg.getInstanceMessageReceiver(LC);
- if (SymbolRef Sym = Receiver.getAsLocSymbol()) {
- if (const RefVal *T = state->get<RefBindings>(Sym)) {
- ReceiverIsTracked = true;
- state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(),
- hasErr, C);
- if (hasErr) {
- ErrorRange = CallOrMsg.getReceiverSourceRange();
- ErrorSym = Sym;
+ if (!hasErr) {
+ const ObjCMethodCall *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg);
+ if (MsgInvocation) {
+ if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
+ if (const RefVal *T = state->get<RefBindings>(Sym)) {
+ ReceiverIsTracked = true;
+ state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(),
+ hasErr, C);
+ if (hasErr) {
+ ErrorRange = MsgInvocation->getReceiverSourceRange();
+ ErrorSym = Sym;
+ }
}
}
}
@@ -2874,9 +2853,9 @@
if (!Sym)
break;
- // Use the result type from callOrMsg as it automatically adjusts
+ // Use the result type from the CallEvent as it automatically adjusts
// for methods/functions that return references.
- QualType ResultTy = CallOrMsg.getResultType(C.getASTContext());
+ QualType ResultTy = CallOrMsg.getResultType();
state = state->set<RefBindings>(Sym, RefVal::makeOwned(RE.getObjKind(),
ResultTy));
@@ -2942,12 +2921,23 @@
IgnoreRetainMsg = (bool)C.getASTContext().getLangOpts().ObjCAutoRefCount;
switch (E) {
- default: break;
- case IncRefMsg: E = IgnoreRetainMsg ? DoNothing : IncRef; break;
- case DecRefMsg: E = IgnoreRetainMsg ? DoNothing : DecRef; break;
- case MakeCollectable: E = C.isObjCGCEnabled() ? DecRef : DoNothing; break;
- case NewAutoreleasePool: E = C.isObjCGCEnabled() ? DoNothing :
- NewAutoreleasePool; break;
+ default:
+ break;
+ case IncRefMsg:
+ E = IgnoreRetainMsg ? DoNothing : IncRef;
+ break;
+ case DecRefMsg:
+ E = IgnoreRetainMsg ? DoNothing : DecRef;
+ break;
+ case DecRefMsgAndStopTracking:
+ E = IgnoreRetainMsg ? StopTracking : DecRefAndStopTracking;
+ break;
+ case MakeCollectable:
+ E = C.isObjCGCEnabled() ? DecRef : DoNothing;
+ break;
+ case NewAutoreleasePool:
+ E = C.isObjCGCEnabled() ? DoNothing : NewAutoreleasePool;
+ break;
}
// Handle all use-after-releases.
@@ -2961,6 +2951,7 @@
case DecRefMsg:
case IncRefMsg:
case MakeCollectable:
+ case DecRefMsgAndStopTracking:
llvm_unreachable("DecRefMsg/IncRefMsg/MakeCollectable already converted");
case Dealloc:
@@ -3031,6 +3022,7 @@
case DecRef:
case DecRefBridgedTransfered:
+ case DecRefAndStopTracking:
switch (V.getKind()) {
default:
// case 'RefVal::Released' handled above.
@@ -3041,13 +3033,18 @@
if (V.getCount() == 1)
V = V ^ (E == DecRefBridgedTransfered ?
RefVal::NotOwned : RefVal::Released);
+ else if (E == DecRefAndStopTracking)
+ return state->remove<RefBindings>(sym);
+
V = V - 1;
break;
case RefVal::NotOwned:
- if (V.getCount() > 0)
+ if (V.getCount() > 0) {
+ if (E == DecRefAndStopTracking)
+ return state->remove<RefBindings>(sym);
V = V - 1;
- else {
+ } else {
V = V ^ RefVal::ErrorReleaseNotOwned;
hasErr = V.getKind();
}
@@ -3281,22 +3278,20 @@
// Consult the summary of the enclosing method.
RetainSummaryManager &Summaries = getSummaryManager(C);
const Decl *CD = &Pred->getCodeDecl();
+ RetEffect RE = RetEffect::MakeNoRet();
+ // FIXME: What is the convention for blocks? Is there one?
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
- // Unlike regular functions, /all/ ObjC methods are assumed to always
- // follow Cocoa retain-count conventions, not just those with special
- // names or attributes.
const RetainSummary *Summ = Summaries.getMethodSummary(MD);
- RetEffect RE = Summ ? Summ->getRetEffect() : RetEffect::MakeNoRet();
- checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
+ RE = Summ->getRetEffect();
+ } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
+ if (!isa<CXXMethodDecl>(FD)) {
+ const RetainSummary *Summ = Summaries.getFunctionSummary(FD);
+ RE = Summ->getRetEffect();
+ }
}
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
- if (!isa<CXXMethodDecl>(FD))
- if (const RetainSummary *Summ = Summaries.getSummary(FD, 0))
- checkReturnWithRetEffect(S, C, Pred, Summ->getRetEffect(), X,
- Sym, state);
- }
+ checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
}
void RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
@@ -3454,7 +3449,7 @@
const StoreManager::InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call) const {
+ const CallEvent *Call) const {
if (!invalidated)
return state;
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/CMakeLists.txt?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/CMakeLists.txt (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/CMakeLists.txt Tue Jul 3 11:18:37 2012
@@ -8,6 +8,7 @@
BlockCounter.cpp
BugReporter.cpp
BugReporterVisitors.cpp
+ Calls.cpp
Checker.cpp
CheckerContext.cpp
CheckerHelpers.cpp
@@ -24,7 +25,6 @@
FunctionSummary.cpp
HTMLDiagnostics.cpp
MemRegion.cpp
- ObjCMessage.cpp
PathDiagnostic.cpp
PlistDiagnostics.cpp
ProgramState.cpp
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerManager.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerManager.cpp Tue Jul 3 11:18:37 2012
@@ -14,7 +14,7 @@
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/Analysis/ProgramPoint.h"
#include "clang/AST/DeclBase.h"
@@ -25,6 +25,8 @@
return !StmtCheckers.empty() ||
!PreObjCMessageCheckers.empty() ||
!PostObjCMessageCheckers.empty() ||
+ !PreCallCheckers.empty() ||
+ !PostCallCheckers.empty() ||
!LocationCheckers.empty() ||
!BindCheckers.empty() ||
!EndAnalysisCheckers.empty() ||
@@ -178,14 +180,14 @@
typedef std::vector<CheckerManager::CheckObjCMessageFunc> CheckersTy;
bool IsPreVisit;
const CheckersTy &Checkers;
- const ObjCMessage &Msg;
+ const ObjCMethodCall &Msg;
ExprEngine &Eng;
CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
CheckObjCMessageContext(bool isPreVisit, const CheckersTy &checkers,
- const ObjCMessage &msg, ExprEngine &eng)
+ const ObjCMethodCall &msg, ExprEngine &eng)
: IsPreVisit(isPreVisit), Checkers(checkers), Msg(msg), Eng(eng) { }
void runChecker(CheckerManager::CheckObjCMessageFunc checkFn,
@@ -193,7 +195,7 @@
ProgramPoint::Kind K = IsPreVisit ? ProgramPoint::PreStmtKind :
ProgramPoint::PostStmtKind;
const ProgramPoint &L =
- ProgramPoint::getProgramPoint(Msg.getMessageExpr(),
+ ProgramPoint::getProgramPoint(Msg.getOriginExpr(),
K, Pred->getLocationContext(),
checkFn.Checker);
CheckerContext C(Bldr, Eng, Pred, L);
@@ -207,7 +209,7 @@
void CheckerManager::runCheckersForObjCMessage(bool isPreVisit,
ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
- const ObjCMessage &msg,
+ const ObjCMethodCall &msg,
ExprEngine &Eng) {
CheckObjCMessageContext C(isPreVisit,
isPreVisit ? PreObjCMessageCheckers
@@ -217,6 +219,54 @@
}
namespace {
+ // FIXME: This has all the same signatures as CheckObjCMessageContext.
+ // Is there a way we can merge the two?
+ struct CheckCallContext {
+ typedef std::vector<CheckerManager::CheckCallFunc> CheckersTy;
+ bool IsPreVisit;
+ const CheckersTy &Checkers;
+ const CallEvent &Call;
+ ExprEngine &Eng;
+
+ CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
+ CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
+
+ CheckCallContext(bool isPreVisit, const CheckersTy &checkers,
+ const CallEvent &call, ExprEngine &eng)
+ : IsPreVisit(isPreVisit), Checkers(checkers), Call(call), Eng(eng) { }
+
+ void runChecker(CheckerManager::CheckCallFunc checkFn,
+ NodeBuilder &Bldr, ExplodedNode *Pred) {
+ // FIXME: This will be wrong as soon as we handle any calls without
+ // associated statements.
+ ProgramPoint::Kind K = IsPreVisit ? ProgramPoint::PreStmtKind
+ : ProgramPoint::PostStmtKind;
+ assert(Call.getOriginExpr() && "Calls without stmts not yet handled");
+ const ProgramPoint &L =
+ ProgramPoint::getProgramPoint(Call.getOriginExpr(),
+ K, Pred->getLocationContext(),
+ checkFn.Checker);
+ CheckerContext C(Bldr, Eng, Pred, L);
+
+ checkFn(Call, C);
+ }
+ };
+}
+
+/// \brief Run checkers for visiting an abstract call event.
+void CheckerManager::runCheckersForCallEvent(bool isPreVisit,
+ ExplodedNodeSet &Dst,
+ const ExplodedNodeSet &Src,
+ const CallEvent &Call,
+ ExprEngine &Eng) {
+ CheckCallContext C(isPreVisit,
+ isPreVisit ? PreCallCheckers
+ : PostCallCheckers,
+ Call, Eng);
+ expandGraphWithCheckers(C, Dst, Src);
+}
+
+namespace {
struct CheckLocationContext {
typedef std::vector<CheckerManager::CheckLocationFunc> CheckersTy;
const CheckersTy &Checkers;
@@ -431,7 +481,7 @@
const StoreManager::InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> ExplicitRegions,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call) {
+ const CallEvent *Call) {
for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) {
// If any checker declares the state infeasible (or if it starts that way),
// bail out.
@@ -461,16 +511,9 @@
/// Only one checker will evaluate the call.
void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst,
const ExplodedNodeSet &Src,
- const CallExpr *CE,
- ExprEngine &Eng,
- GraphExpander *defaultEval) {
- if (EvalCallCheckers.empty() &&
- InlineCallCheckers.empty() &&
- defaultEval == 0) {
- Dst.insert(Src);
- return;
- }
-
+ const SimpleCall &Call,
+ ExprEngine &Eng) {
+ const CallExpr *CE = Call.getOriginExpr();
for (ExplodedNodeSet::iterator
NI = Src.begin(), NE = Src.end(); NI != NE; ++NI) {
@@ -533,12 +576,8 @@
}
// If none of the checkers evaluated the call, ask ExprEngine to handle it.
- if (!anyEvaluated) {
- if (defaultEval)
- defaultEval->expandGraph(Dst, Pred);
- else
- Dst.insert(Pred);
- }
+ if (!anyEvaluated)
+ Eng.defaultEvalCall(Dst, Pred, Call);
}
}
@@ -595,6 +634,13 @@
PostObjCMessageCheckers.push_back(checkfn);
}
+void CheckerManager::_registerForPreCall(CheckCallFunc checkfn) {
+ PreCallCheckers.push_back(checkfn);
+}
+void CheckerManager::_registerForPostCall(CheckCallFunc checkfn) {
+ PostCallCheckers.push_back(checkfn);
+}
+
void CheckerManager::_registerForLocation(CheckLocationFunc checkfn) {
LocationCheckers.push_back(checkfn);
}
@@ -678,6 +724,3 @@
for (unsigned i = 0, e = CheckerDtors.size(); i != e; ++i)
CheckerDtors[i]();
}
-
-// Anchor for the vtable.
-GraphExpander::~GraphExpander() { }
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ExplodedGraph.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExplodedGraph.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExplodedGraph.cpp Tue Jul 3 11:18:37 2012
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/ParentMap.h"
@@ -69,7 +69,7 @@
// (6) The 'GDM' is the same as the predecessor.
// (7) The LocationContext is the same as the predecessor.
// (8) The PostStmt is for a non-consumed Stmt or Expr.
- // (9) The successor is a CallExpr StmtPoint (so that we would be able to
+ // (9) The successor is not a CallExpr StmtPoint (so that we would be able to
// find it when retrying a call with no inlining).
// Conditions 1 and 2.
@@ -116,7 +116,7 @@
// Condition 9.
const ProgramPoint SuccLoc = succ->getLocation();
if (const StmtPoint *SP = dyn_cast<StmtPoint>(&SuccLoc))
- if (CallOrObjCMessage::canBeInlined(SP->getStmt()))
+ if (CallEvent::mayBeInlined(SP->getStmt()))
return false;
return true;
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Jul 3 11:18:37 2012
@@ -18,8 +18,8 @@
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/ParentMap.h"
#include "clang/AST/StmtObjC.h"
@@ -185,7 +185,7 @@
const StoreManager::InvalidatedSymbols *invalidated,
ArrayRef<const MemRegion *> Explicits,
ArrayRef<const MemRegion *> Regions,
- const CallOrObjCMessage *Call) {
+ const CallEvent *Call) {
return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
Explicits, Regions, Call);
}
@@ -241,7 +241,7 @@
return true;
// Run before processing a call.
- if (CallOrObjCMessage::canBeInlined(S.getStmt()))
+ if (CallEvent::mayBeInlined(S.getStmt()))
return true;
// Is this an expression that is consumed by another expression? If so,
@@ -866,26 +866,33 @@
case Stmt::ObjCMessageExprClass: {
Bldr.takeNodes(Pred);
// Is this a property access?
- const ParentMap &PM = Pred->getLocationContext()->getParentMap();
+
+ const LocationContext *LCtx = Pred->getLocationContext();
+ const ParentMap &PM = LCtx->getParentMap();
const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(S);
bool evaluated = false;
if (const PseudoObjectExpr *PO =
- dyn_cast_or_null<PseudoObjectExpr>(PM.getParent(S))) {
+ dyn_cast_or_null<PseudoObjectExpr>(PM.getParent(S))) {
const Expr *syntactic = PO->getSyntacticForm();
+
+ // This handles the funny case of assigning to the result of a getter.
+ // This can happen if the getter returns a non-const reference.
+ if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(syntactic))
+ syntactic = BO->getLHS();
+
if (const ObjCPropertyRefExpr *PR =
dyn_cast<ObjCPropertyRefExpr>(syntactic)) {
- bool isSetter = ME->getNumArgs() > 0;
- VisitObjCMessage(ObjCMessage(ME, PR, isSetter), Pred, Dst);
+ VisitObjCMessage(ObjCPropertyAccess(PR, PO->getSourceRange(), ME,
+ Pred->getState(), LCtx),
+ Pred, Dst);
evaluated = true;
}
- else if (isa<BinaryOperator>(syntactic)) {
- VisitObjCMessage(ObjCMessage(ME, 0, true), Pred, Dst);
- }
}
if (!evaluated)
- VisitObjCMessage(ME, Pred, Dst);
+ VisitObjCMessage(ObjCMessageSend(ME, Pred->getState(), LCtx),
+ Pred, Dst);
Bldr.addNodes(Dst);
break;
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Tue Jul 3 11:18:37 2012
@@ -14,7 +14,7 @@
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/StmtCXX.h"
@@ -46,91 +46,28 @@
VisitCXXConstructExpr(expr, 0, Pred, Dst);
}
-void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
+void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
const MemRegion *Dest,
ExplodedNode *Pred,
ExplodedNodeSet &destNodes) {
+ CXXConstructorCall Call(CE, Dest, Pred->getState(),
+ Pred->getLocationContext());
-#if 0
- const CXXConstructorDecl *CD = E->getConstructor();
- assert(CD);
-#endif
-
-#if 0
- if (!(CD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall()))
- // FIXME: invalidate the object.
- return;
-#endif
-
-#if 0
- // Is the constructor elidable?
- if (E->isElidable()) {
- destNodes.Add(Pred);
- return;
- }
-#endif
-
- // Perform the previsit of the constructor.
- ExplodedNodeSet SrcNodes;
- SrcNodes.Add(Pred);
- ExplodedNodeSet TmpNodes;
- getCheckerManager().runCheckersForPreStmt(TmpNodes, SrcNodes, E, *this);
-
- // Evaluate the constructor. Currently we don't now allow checker-specific
- // implementations of specific constructors (as we do with ordinary
- // function calls. We can re-evaluate this in the future.
-
-#if 0
- // Inlining currently isn't fully implemented.
-
- if (AMgr.shouldInlineCall()) {
- if (!Dest)
- Dest =
- svalBuilder.getRegionManager().getCXXTempObjectRegion(E,
- Pred->getLocationContext());
-
- // The callee stack frame context used to create the 'this'
- // parameter region.
- const StackFrameContext *SFC =
- AMgr.getStackFrame(CD, Pred->getLocationContext(),
- E, currentBuilderContext->getBlock(),
- currentStmtIdx);
-
- // Create the 'this' region.
- const CXXThisRegion *ThisR =
- getCXXThisRegion(E->getConstructor()->getParent(), SFC);
-
- CallEnter Loc(E, SFC, Pred->getLocationContext());
-
- StmtNodeBuilder Bldr(SrcNodes, TmpNodes, *currentBuilderContext);
- for (ExplodedNodeSet::iterator NI = SrcNodes.begin(),
- NE = SrcNodes.end(); NI != NE; ++NI) {
- ProgramStateRef state = (*NI)->getState();
- // Setup 'this' region, so that the ctor is evaluated on the object pointed
- // by 'Dest'.
- state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
- Bldr.generateNode(Loc, *NI, state);
- }
- }
-#endif
-
- // Default semantics: invalidate all regions passed as arguments.
- ExplodedNodeSet destCall;
- {
- StmtNodeBuilder Bldr(TmpNodes, destCall, *currentBuilderContext);
- for (ExplodedNodeSet::iterator i = TmpNodes.begin(), e = TmpNodes.end();
- i != e; ++i)
- {
- ExplodedNode *Pred = *i;
- const LocationContext *LC = Pred->getLocationContext();
- ProgramStateRef state = Pred->getState();
-
- state = invalidateArguments(state, CallOrObjCMessage(E, state, LC), LC);
- Bldr.generateNode(E, Pred, state);
- }
- }
- // Do the post visit.
- getCheckerManager().runCheckersForPostStmt(destNodes, destCall, E, *this);
+ ExplodedNodeSet DstPreVisit;
+ getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this);
+ ExplodedNodeSet DstPreCall;
+ getCheckerManager().runCheckersForPreCall(DstPreCall, DstPreVisit,
+ Call, *this);
+
+ ExplodedNodeSet DstInvalidated;
+ for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
+ I != E; ++I)
+ defaultEvalCall(DstInvalidated, *I, Call);
+
+ ExplodedNodeSet DstPostCall;
+ getCheckerManager().runCheckersForPostCall(DstPostCall, DstInvalidated,
+ Call, *this);
+ getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this);
}
void ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD,
@@ -155,191 +92,51 @@
Bldr.generateNode(PP, Pred, state);
}
-static bool isPointerToConst(const ParmVarDecl *ParamDecl) {
- // FIXME: Copied from ExprEngineCallAndReturn.cpp
- QualType PointeeTy = ParamDecl->getOriginalType()->getPointeeType();
- if (PointeeTy != QualType() && PointeeTy.isConstQualified() &&
- !PointeeTy->isAnyPointerType() && !PointeeTy->isReferenceType()) {
- return true;
- }
- return false;
-}
-
void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
+ // FIXME: Much of this should eventually migrate to CXXAllocatorCall.
+ // Also, we need to decide how allocators actually work -- they're not
+ // really part of the CXXNewExpr because they happen BEFORE the
+ // CXXConstructExpr subexpression. See PR12014 for some discussion.
StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
unsigned blockCount = currentBuilderContext->getCurrentBlockCount();
const LocationContext *LCtx = Pred->getLocationContext();
DefinedOrUnknownSVal symVal =
- svalBuilder.getConjuredSymbolVal(NULL, CNE, LCtx, CNE->getType(), blockCount);
- const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion();
- QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
- const ElementRegion *EleReg =
- getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
+ svalBuilder.getConjuredSymbolVal(0, CNE, LCtx, CNE->getType(), blockCount);
ProgramStateRef State = Pred->getState();
+ // Invalidate placement args.
+ CXXAllocatorCall Call(CNE, State, LCtx);
+ State = Call.invalidateRegions(blockCount);
+
if (CNE->isArray()) {
// FIXME: allocating an array requires simulating the constructors.
// For now, just return a symbolicated region.
+ const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion();
+ QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
+ const ElementRegion *EleReg =
+ getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
State = State->BindExpr(CNE, Pred->getLocationContext(),
loc::MemRegionVal(EleReg));
Bldr.generateNode(CNE, Pred, State);
return;
}
+ // FIXME: Once we have proper support for CXXConstructExprs inside
+ // CXXNewExpr, we need to make sure that the constructed object is not
+ // immediately invalidated here. (The placement call should happen before
+ // the constructor call anyway.)
FunctionDecl *FD = CNE->getOperatorNew();
if (FD && FD->isReservedGlobalPlacementOperator()) {
// Non-array placement new should always return the placement location.
SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx);
State = State->BindExpr(CNE, LCtx, PlacementLoc);
- // FIXME: Once we have proper support for CXXConstructExprs inside
- // CXXNewExpr, we need to make sure that the constructed object is not
- // immediately invalidated here. (The placement call should happen before
- // the constructor call anyway.)
+ } else {
+ State = State->BindExpr(CNE, LCtx, symVal);
}
- // Invalidate placement args.
-
- // FIXME: This is largely copied from invalidateArguments, because
- // CallOrObjCMessage is not general enough to handle new-expressions yet.
- SmallVector<const MemRegion *, 4> RegionsToInvalidate;
-
- unsigned Index = 0;
- for (CXXNewExpr::const_arg_iterator I = CNE->placement_arg_begin(),
- E = CNE->placement_arg_end();
- I != E; ++I) {
- // Pre-increment the argument index to skip over the implicit size arg.
- ++Index;
- if (FD && Index < FD->getNumParams())
- if (isPointerToConst(FD->getParamDecl(Index)))
- continue;
-
- SVal V = State->getSVal(*I, LCtx);
-
- // If we are passing a location wrapped as an integer, unwrap it and
- // invalidate the values referred by the location.
- if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
- V = Wrapped->getLoc();
- else if (!isa<Loc>(V))
- continue;
-
- if (const MemRegion *R = V.getAsRegion()) {
- // Invalidate the value of the variable passed by reference.
-
- // Are we dealing with an ElementRegion? If the element type is
- // a basic integer type (e.g., char, int) and the underlying region
- // is a variable region then strip off the ElementRegion.
- // FIXME: We really need to think about this for the general case
- // as sometimes we are reasoning about arrays and other times
- // about (char*), etc., is just a form of passing raw bytes.
- // e.g., void *p = alloca(); foo((char*)p);
- if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
- // Checking for 'integral type' is probably too promiscuous, but
- // we'll leave it in for now until we have a systematic way of
- // handling all of these cases. Eventually we need to come up
- // with an interface to StoreManager so that this logic can be
- // appropriately delegated to the respective StoreManagers while
- // still allowing us to do checker-specific logic (e.g.,
- // invalidating reference counts), probably via callbacks.
- if (ER->getElementType()->isIntegralOrEnumerationType()) {
- const MemRegion *superReg = ER->getSuperRegion();
- if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
- isa<ObjCIvarRegion>(superReg))
- R = cast<TypedRegion>(superReg);
- }
- // FIXME: What about layers of ElementRegions?
- }
-
- // Mark this region for invalidation. We batch invalidate regions
- // below for efficiency.
- RegionsToInvalidate.push_back(R);
- } else {
- // Nuke all other arguments passed by reference.
- // FIXME: is this necessary or correct? This handles the non-Region
- // cases. Is it ever valid to store to these?
- State = State->unbindLoc(cast<Loc>(V));
- }
- }
-
- // Invalidate designated regions using the batch invalidation API.
-
- // FIXME: We can have collisions on the conjured symbol if the
- // expression *I also creates conjured symbols. We probably want
- // to identify conjured symbols by an expression pair: the enclosing
- // expression (the context) and the expression itself. This should
- // disambiguate conjured symbols.
- unsigned Count = currentBuilderContext->getCurrentBlockCount();
-
- // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
- // global variables.
- State = State->invalidateRegions(RegionsToInvalidate, CNE, Count, LCtx);
Bldr.generateNode(CNE, Pred, State);
- return;
-
- // FIXME: The below code is long-since dead. However, constructor handling
- // in new-expressions is far from complete. See PR12014 for more details.
-#if 0
- // Evaluate constructor arguments.
- const FunctionProtoType *FnType = NULL;
- const CXXConstructorDecl *CD = CNE->getConstructor();
- if (CD)
- FnType = CD->getType()->getAs<FunctionProtoType>();
- ExplodedNodeSet argsEvaluated;
- Bldr.takeNodes(Pred);
- evalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(),
- FnType, Pred, argsEvaluated);
- Bldr.addNodes(argsEvaluated);
-
- // Initialize the object region and bind the 'new' expression.
- for (ExplodedNodeSet::iterator I = argsEvaluated.begin(),
- E = argsEvaluated.end(); I != E; ++I) {
-
- ProgramStateRef state = (*I)->getState();
-
- // Accumulate list of regions that are invalidated.
- // FIXME: Eventually we should unify the logic for constructor
- // processing in one place.
- SmallVector<const MemRegion*, 10> regionsToInvalidate;
- for (CXXNewExpr::const_arg_iterator
- ai = CNE->constructor_arg_begin(), ae = CNE->constructor_arg_end();
- ai != ae; ++ai)
- {
- SVal val = state->getSVal(*ai, (*I)->getLocationContext());
- if (const MemRegion *region = val.getAsRegion())
- regionsToInvalidate.push_back(region);
- }
-
- if (ObjTy->isRecordType()) {
- regionsToInvalidate.push_back(EleReg);
- // Invalidate the regions.
- // TODO: Pass the call to new information as the last argument, to limit
- // the globals which will get invalidated.
- state = state->invalidateRegions(regionsToInvalidate,
- CNE, blockCount, 0, 0);
-
- } else {
- // Invalidate the regions.
- // TODO: Pass the call to new information as the last argument, to limit
- // the globals which will get invalidated.
- state = state->invalidateRegions(regionsToInvalidate,
- CNE, blockCount, 0, 0);
-
- if (CNE->hasInitializer()) {
- SVal V = state->getSVal(*CNE->constructor_arg_begin(),
- (*I)->getLocationContext());
- state = state->bindLoc(loc::MemRegionVal(EleReg), V);
- } else {
- // Explicitly set to undefined, because currently we retrieve symbolic
- // value from symbolic region.
- state = state->bindLoc(loc::MemRegionVal(EleReg), UndefinedVal());
- }
- }
- state = state->BindExpr(CNE, (*I)->getLocationContext(),
- loc::MemRegionVal(EleReg));
- Bldr.generateNode(CNE, *I, state);
- }
-#endif
}
void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Tue Jul 3 11:18:37 2012
@@ -11,9 +11,10 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/AST/DeclCXX.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Support/SaveAndRestore.h"
@@ -207,6 +208,10 @@
// Determine if we should inline the call.
bool ExprEngine::shouldInlineDecl(const Decl *D, ExplodedNode *Pred) {
+ // FIXME: default constructors don't have bodies.
+ if (!D->hasBody())
+ return false;
+
AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(D);
const CFG *CalleeCFG = CalleeADC->getCFG();
@@ -235,52 +240,54 @@
return false;
}
+ // It is possible that the live variables analysis cannot be
+ // run. If so, bail out.
+ if (!CalleeADC->getAnalysis<RelaxedLiveVariables>())
+ return false;
+
return true;
}
-bool ExprEngine::InlineCall(ExplodedNodeSet &Dst,
- const CallExpr *CE,
+bool ExprEngine::inlineCall(ExplodedNodeSet &Dst,
+ const CallEvent &Call,
ExplodedNode *Pred) {
if (!getAnalysisManager().shouldInlineCall())
return false;
- // if (!shouldInlineCallExpr(CE, this))
- // return false;
-
const StackFrameContext *CallerSFC =
Pred->getLocationContext()->getCurrentStackFrame();
- ProgramStateRef state = Pred->getState();
- const Expr *Callee = CE->getCallee();
- SVal CalleeVal = state->getSVal(Callee, Pred->getLocationContext());
- const Decl *D = 0;
+ const Decl *D = Call.getDecl();
const LocationContext *ParentOfCallee = 0;
-
- if (const FunctionDecl *FD = CalleeVal.getAsFunctionDecl()) {
- if (!FD->hasBody(FD))
+
+ switch (Call.getKind()) {
+ case CE_Function:
+ case CE_CXXMember:
+ // These are always at least possible to inline.
+ break;
+ case CE_CXXConstructor:
+ // Do not inline constructors until we can model destructors.
+ // This is unfortunate, but basically necessary for smart pointers and such.
+ return false;
+ case CE_CXXAllocator:
+ // Do not inline allocators until we model deallocators.
+ // This is unfortunate, but basically necessary for smart pointers and such.
+ return false;
+ case CE_Block: {
+ const BlockDataRegion *BR = cast<BlockCall>(Call).getBlockRegion();
+ if (!BR)
return false;
-
- switch (CE->getStmtClass()) {
- default:
- break;
- case Stmt::CXXMemberCallExprClass:
- case Stmt::CallExprClass: {
- D = FD;
- break;
-
- }
- }
- } else if (const BlockDataRegion *BR =
- dyn_cast_or_null<BlockDataRegion>(CalleeVal.getAsRegion())) {
- assert(CE->getStmtClass() == Stmt::CallExprClass);
- const BlockDecl *BD = BR->getDecl();
- D = BD;
- AnalysisDeclContext *BlockCtx = AMgr.getAnalysisDeclContext(BD);
+ D = BR->getDecl();
+ AnalysisDeclContext *BlockCtx = AMgr.getAnalysisDeclContext(D);
ParentOfCallee = BlockCtx->getBlockInvocationContext(CallerSFC,
- BD,
+ cast<BlockDecl>(D),
BR);
- } else {
- // This is case we don't handle yet.
+ break;
+ }
+ case CE_ObjCMessage:
+ case CE_ObjCPropertyAccess:
+ // These always use dynamic dispatch; enabling inlining means assuming
+ // that a particular method will be called at runtime.
return false;
}
@@ -290,16 +297,19 @@
if (!ParentOfCallee)
ParentOfCallee = CallerSFC;
+ const Expr *CallE = Call.getOriginExpr();
+ assert(CallE && "It is not yet possible to have calls without statements");
+
// Construct a new stack frame for the callee.
AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(D);
const StackFrameContext *CalleeSFC =
- CalleeADC->getStackFrame(ParentOfCallee, CE,
+ CalleeADC->getStackFrame(ParentOfCallee, CallE,
currentBuilderContext->getBlock(),
currentStmtIdx);
- CallEnter Loc(CE, CalleeSFC, Pred->getLocationContext());
+ CallEnter Loc(CallE, CalleeSFC, Pred->getLocationContext());
bool isNew;
- if (ExplodedNode *N = G.getNode(Loc, state, false, &isNew)) {
+ if (ExplodedNode *N = G.getNode(Loc, Pred->getState(), false, &isNew)) {
N->addPredecessor(Pred, G);
if (isNew)
Engine.getWorkList()->enqueue(N);
@@ -307,186 +317,13 @@
return true;
}
-static bool isPointerToConst(const ParmVarDecl *ParamDecl) {
- QualType PointeeTy = ParamDecl->getOriginalType()->getPointeeType();
- if (PointeeTy != QualType() && PointeeTy.isConstQualified() &&
- !PointeeTy->isAnyPointerType() && !PointeeTy->isReferenceType()) {
- return true;
- }
- return false;
-}
-
-// Try to retrieve the function declaration and find the function parameter
-// types which are pointers/references to a non-pointer const.
-// We do not invalidate the corresponding argument regions.
-static void findPtrToConstParams(llvm::SmallSet<unsigned, 1> &PreserveArgs,
- const CallOrObjCMessage &Call) {
- const Decl *CallDecl = Call.getDecl();
- if (!CallDecl)
- return;
-
- if (const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(CallDecl)) {
- const IdentifierInfo *II = FDecl->getIdentifier();
-
- // List the cases, where the region should be invalidated even if the
- // argument is const.
- if (II) {
- StringRef FName = II->getName();
- // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
- // value into thread local storage. The value can later be retrieved with
- // 'void *ptheread_getspecific(pthread_key)'. So even thought the
- // parameter is 'const void *', the region escapes through the call.
- // - funopen - sets a buffer for future IO calls.
- // - ObjC functions that end with "NoCopy" can free memory, of the passed
- // in buffer.
- // - Many CF containers allow objects to escape through custom
- // allocators/deallocators upon container construction.
- // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
- // be deallocated by NSMapRemove.
- // - Any call that has a callback as one of the arguments.
- if (FName == "pthread_setspecific" ||
- FName == "funopen" ||
- FName.endswith("NoCopy") ||
- (FName.startswith("NS") &&
- (FName.find("Insert") != StringRef::npos)) ||
- Call.isCFCGAllowingEscape(FName) ||
- Call.hasNonZeroCallbackArg())
- return;
- }
-
- for (unsigned Idx = 0, E = Call.getNumArgs(); Idx != E; ++Idx) {
- if (FDecl && Idx < FDecl->getNumParams()) {
- if (isPointerToConst(FDecl->getParamDecl(Idx)))
- PreserveArgs.insert(Idx);
- }
- }
- return;
- }
-
- if (const ObjCMethodDecl *MDecl = dyn_cast<ObjCMethodDecl>(CallDecl)) {
- assert(MDecl->param_size() <= Call.getNumArgs());
- unsigned Idx = 0;
-
- if (Call.hasNonZeroCallbackArg())
- return;
-
- for (clang::ObjCMethodDecl::param_const_iterator
- I = MDecl->param_begin(), E = MDecl->param_end(); I != E; ++I, ++Idx) {
- if (isPointerToConst(*I))
- PreserveArgs.insert(Idx);
- }
- return;
- }
-}
-
-ProgramStateRef
-ExprEngine::invalidateArguments(ProgramStateRef State,
- const CallOrObjCMessage &Call,
- const LocationContext *LC) {
- SmallVector<const MemRegion *, 8> RegionsToInvalidate;
-
- if (Call.isObjCMessage()) {
- // Invalidate all instance variables of the receiver of an ObjC message.
- // FIXME: We should be able to do better with inter-procedural analysis.
- if (const MemRegion *MR = Call.getInstanceMessageReceiver(LC).getAsRegion())
- RegionsToInvalidate.push_back(MR);
-
- } else if (Call.isCXXCall()) {
- // Invalidate all instance variables for the callee of a C++ method call.
- // FIXME: We should be able to do better with inter-procedural analysis.
- // FIXME: We can probably do better for const versus non-const methods.
- if (const MemRegion *Callee = Call.getCXXCallee().getAsRegion())
- RegionsToInvalidate.push_back(Callee);
-
- } else if (Call.isFunctionCall()) {
- // Block calls invalidate all captured-by-reference values.
- SVal CalleeVal = Call.getFunctionCallee();
- if (const MemRegion *Callee = CalleeVal.getAsRegion()) {
- if (isa<BlockDataRegion>(Callee))
- RegionsToInvalidate.push_back(Callee);
- }
- }
-
- // Indexes of arguments whose values will be preserved by the call.
- llvm::SmallSet<unsigned, 1> PreserveArgs;
- findPtrToConstParams(PreserveArgs, Call);
-
- for (unsigned idx = 0, e = Call.getNumArgs(); idx != e; ++idx) {
- if (PreserveArgs.count(idx))
- continue;
-
- SVal V = Call.getArgSVal(idx);
-
- // If we are passing a location wrapped as an integer, unwrap it and
- // invalidate the values referred by the location.
- if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
- V = Wrapped->getLoc();
- else if (!isa<Loc>(V))
- continue;
-
- if (const MemRegion *R = V.getAsRegion()) {
- // Invalidate the value of the variable passed by reference.
-
- // Are we dealing with an ElementRegion? If the element type is
- // a basic integer type (e.g., char, int) and the underlying region
- // is a variable region then strip off the ElementRegion.
- // FIXME: We really need to think about this for the general case
- // as sometimes we are reasoning about arrays and other times
- // about (char*), etc., is just a form of passing raw bytes.
- // e.g., void *p = alloca(); foo((char*)p);
- if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
- // Checking for 'integral type' is probably too promiscuous, but
- // we'll leave it in for now until we have a systematic way of
- // handling all of these cases. Eventually we need to come up
- // with an interface to StoreManager so that this logic can be
- // appropriately delegated to the respective StoreManagers while
- // still allowing us to do checker-specific logic (e.g.,
- // invalidating reference counts), probably via callbacks.
- if (ER->getElementType()->isIntegralOrEnumerationType()) {
- const MemRegion *superReg = ER->getSuperRegion();
- if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
- isa<ObjCIvarRegion>(superReg))
- R = cast<TypedRegion>(superReg);
- }
- // FIXME: What about layers of ElementRegions?
- }
-
- // Mark this region for invalidation. We batch invalidate regions
- // below for efficiency.
- RegionsToInvalidate.push_back(R);
- } else {
- // Nuke all other arguments passed by reference.
- // FIXME: is this necessary or correct? This handles the non-Region
- // cases. Is it ever valid to store to these?
- State = State->unbindLoc(cast<Loc>(V));
- }
- }
-
- // Invalidate designated regions using the batch invalidation API.
-
- // FIXME: We can have collisions on the conjured symbol if the
- // expression *I also creates conjured symbols. We probably want
- // to identify conjured symbols by an expression pair: the enclosing
- // expression (the context) and the expression itself. This should
- // disambiguate conjured symbols.
- unsigned Count = currentBuilderContext->getCurrentBlockCount();
- StoreManager::InvalidatedSymbols IS;
-
- // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
- // global variables.
- return State->invalidateRegions(RegionsToInvalidate,
- Call.getOriginExpr(), Count, LC,
- &IS, &Call);
-
-}
-
-static ProgramStateRef getReplayWithoutInliningState(ExplodedNode *&N,
- const CallExpr *CE) {
+static ProgramStateRef getInlineFailedState(ExplodedNode *&N,
+ const Stmt *CallE) {
void *ReplayState = N->getState()->get<ReplayWithoutInlining>();
if (!ReplayState)
return 0;
- const CallExpr *ReplayCE = reinterpret_cast<const CallExpr*>(ReplayState);
- if (CE == ReplayCE) {
+ const Stmt *ReplayCallE = reinterpret_cast<const Stmt *>(ReplayState);
+ if (CallE == ReplayCallE) {
return N->getState()->remove<ReplayWithoutInlining>();
}
return 0;
@@ -497,74 +334,88 @@
// Perform the previsit of the CallExpr.
ExplodedNodeSet dstPreVisit;
getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, CE, *this);
-
- // Now evaluate the call itself.
- class DefaultEval : public GraphExpander {
- ExprEngine &Eng;
- const CallExpr *CE;
- public:
-
- DefaultEval(ExprEngine &eng, const CallExpr *ce)
- : Eng(eng), CE(ce) {}
- virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) {
-
- ProgramStateRef state = getReplayWithoutInliningState(Pred, CE);
-
- // First, try to inline the call.
- if (state == 0 && Eng.InlineCall(Dst, CE, Pred))
- return;
-
- // First handle the return value.
- StmtNodeBuilder Bldr(Pred, Dst, *Eng.currentBuilderContext);
-
- // Get the callee.
- const Expr *Callee = CE->getCallee()->IgnoreParens();
- if (state == 0)
- state = Pred->getState();
- SVal L = state->getSVal(Callee, Pred->getLocationContext());
-
- // Figure out the result type. We do this dance to handle references.
- QualType ResultTy;
- if (const FunctionDecl *FD = L.getAsFunctionDecl())
- ResultTy = FD->getResultType();
- else
- ResultTy = CE->getType();
-
- if (CE->isGLValue())
- ResultTy = Eng.getContext().getPointerType(ResultTy);
-
- // Conjure a symbol value to use as the result.
- SValBuilder &SVB = Eng.getSValBuilder();
- unsigned Count = Eng.currentBuilderContext->getCurrentBlockCount();
- const LocationContext *LCtx = Pred->getLocationContext();
- SVal RetVal = SVB.getConjuredSymbolVal(0, CE, LCtx, ResultTy, Count);
-
- // Generate a new state with the return value set.
- state = state->BindExpr(CE, LCtx, RetVal);
-
- // Invalidate the arguments.
- state = Eng.invalidateArguments(state, CallOrObjCMessage(CE, state, LCtx),
- LCtx);
- // And make the result node.
- Bldr.generateNode(CE, Pred, state);
- }
- };
-
- // Finally, evaluate the function call. We try each of the checkers
+ // Get the callee kind.
+ const CXXMemberCallExpr *MemberCE = dyn_cast<CXXMemberCallExpr>(CE);
+ bool IsBlock = (MemberCE ? false
+ : CE->getCallee()->getType()->isBlockPointerType());
+
+ // Evaluate the function call. We try each of the checkers
// to see if the can evaluate the function call.
ExplodedNodeSet dstCallEvaluated;
- DefaultEval defEval(*this, CE);
- getCheckerManager().runCheckersForEvalCall(dstCallEvaluated,
- dstPreVisit,
- CE, *this, &defEval);
-
+ for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
+ I != E; ++I) {
+ ProgramStateRef State = (*I)->getState();
+ const LocationContext *LCtx = (*I)->getLocationContext();
+
+ // Evaluate the call.
+ if (MemberCE)
+ evalCall(dstCallEvaluated, *I, CXXMemberCall(MemberCE, State, LCtx));
+ else if (IsBlock)
+ evalCall(dstCallEvaluated, *I, BlockCall(CE, State, LCtx));
+ else
+ evalCall(dstCallEvaluated, *I, FunctionCall(CE, State, LCtx));
+ }
+
// Finally, perform the post-condition check of the CallExpr and store
// the created nodes in 'Dst'.
+ // Note that if the call was inlined, dstCallEvaluated will be empty.
+ // The post-CallExpr check will occur in processCallExit.
getCheckerManager().runCheckersForPostStmt(dst, dstCallEvaluated, CE,
*this);
}
+void ExprEngine::evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
+ const SimpleCall &Call) {
+ // Run any pre-call checks using the generic call interface.
+ ExplodedNodeSet dstPreVisit;
+ getCheckerManager().runCheckersForPreCall(dstPreVisit, Pred, Call, *this);
+
+ // Actually evaluate the function call. We try each of the checkers
+ // to see if the can evaluate the function call, and get a callback at
+ // defaultEvalCall if all of them fail.
+ ExplodedNodeSet dstCallEvaluated;
+ getCheckerManager().runCheckersForEvalCall(dstCallEvaluated, dstPreVisit,
+ Call, *this);
+
+ // Finally, run any post-call checks.
+ getCheckerManager().runCheckersForPostCall(Dst, dstCallEvaluated,
+ Call, *this);
+}
+
+void ExprEngine::defaultEvalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
+ const CallEvent &Call) {
+ // Try to inline the call.
+ ProgramStateRef state = 0;
+ const Expr *E = Call.getOriginExpr();
+ if (E) {
+ state = getInlineFailedState(Pred, E);
+ if (state == 0 && inlineCall(Dst, Call, Pred))
+ return;
+ }
+
+ // If we can't inline it, handle the return value and invalidate the regions.
+ StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
+
+ // Invalidate any regions touched by the call.
+ unsigned Count = currentBuilderContext->getCurrentBlockCount();
+ if (state == 0)
+ state = Pred->getState();
+ state = Call.invalidateRegions(Count, state);
+
+ // Conjure a symbol value to use as the result.
+ assert(Call.getOriginExpr() && "Must have an expression to bind the result");
+ QualType ResultTy = Call.getResultType();
+ SValBuilder &SVB = getSValBuilder();
+ const LocationContext *LCtx = Pred->getLocationContext();
+ SVal RetVal = SVB.getConjuredSymbolVal(0, Call.getOriginExpr(), LCtx,
+ ResultTy, Count);
+
+ // And make the result node.
+ state = state->BindExpr(Call.getOriginExpr(), LCtx, RetVal);
+ Bldr.generateNode(Call.getOriginExpr(), Pred, state);
+}
+
void ExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp Tue Jul 3 11:18:37 2012
@@ -13,8 +13,8 @@
#include "clang/AST/StmtObjC.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
using namespace clang;
using namespace ento;
@@ -140,37 +140,42 @@
return isSubclass(Class->getSuperClass(), II);
}
-void ExprEngine::VisitObjCMessage(const ObjCMessage &msg,
+void ExprEngine::VisitObjCMessage(const ObjCMethodCall &msg,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
// Handle the previsits checks.
ExplodedNodeSet dstPrevisit;
- getCheckerManager().runCheckersForPreObjCMessage(dstPrevisit, Pred,
+ getCheckerManager().runCheckersForPreObjCMessage(dstPrevisit, Pred,
msg, *this);
-
+ ExplodedNodeSet dstGenericPrevisit;
+ getCheckerManager().runCheckersForPreCall(dstGenericPrevisit, dstPrevisit,
+ msg, *this);
+
// Proceed with evaluate the message expression.
ExplodedNodeSet dstEval;
- StmtNodeBuilder Bldr(dstPrevisit, dstEval, *currentBuilderContext);
+ StmtNodeBuilder Bldr(dstGenericPrevisit, dstEval, *currentBuilderContext);
- for (ExplodedNodeSet::iterator DI = dstPrevisit.begin(),
- DE = dstPrevisit.end(); DI != DE; ++DI) {
+ for (ExplodedNodeSet::iterator DI = dstGenericPrevisit.begin(),
+ DE = dstGenericPrevisit.end(); DI != DE; ++DI) {
ExplodedNode *Pred = *DI;
bool RaisesException = false;
- if (const Expr *Receiver = msg.getInstanceReceiver()) {
- ProgramStateRef state = Pred->getState();
- SVal recVal = state->getSVal(Receiver, Pred->getLocationContext());
+ if (msg.isInstanceMessage()) {
+ SVal recVal = msg.getReceiverSVal();
if (!recVal.isUndef()) {
// Bifurcate the state into nil and non-nil ones.
DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
+ ProgramStateRef state = Pred->getState();
ProgramStateRef notNilState, nilState;
llvm::tie(notNilState, nilState) = state->assume(receiverVal);
// There are three cases: can be nil or non-nil, must be nil, must be
// non-nil. We ignore must be nil, and merge the rest two into non-nil.
+ // FIXME: This ignores many potential bugs (<rdar://problem/11733396>).
+ // Revisit once we have lazier constraints.
if (nilState && !notNilState) {
continue;
}
@@ -185,12 +190,9 @@
// Dispatch to plug-in transfer function.
evalObjCMessage(Bldr, msg, Pred, notNilState, RaisesException);
}
- } else if (const ObjCInterfaceDecl *Iface = msg.getReceiverInterface()) {
- // Note that this branch also handles messages to super, not just
- // class methods!
-
+ } else {
// Check for special class methods.
- if (!msg.isInstanceMessage()) {
+ if (const ObjCInterfaceDecl *Iface = msg.getReceiverInterface()) {
if (!NSExceptionII) {
ASTContext &Ctx = getContext();
NSExceptionII = &Ctx.Idents.get("NSException");
@@ -236,13 +238,17 @@
}
}
+ ExplodedNodeSet dstPostvisit;
+ getCheckerManager().runCheckersForPostCall(dstPostvisit, dstEval, msg, *this);
+
// Finally, perform the post-condition check of the ObjCMessageExpr and store
// the created nodes in 'Dst'.
- getCheckerManager().runCheckersForPostObjCMessage(Dst, dstEval, msg, *this);
+ getCheckerManager().runCheckersForPostObjCMessage(Dst, dstPostvisit,
+ msg, *this);
}
void ExprEngine::evalObjCMessage(StmtNodeBuilder &Bldr,
- const ObjCMessage &msg,
+ const ObjCMethodCall &msg,
ExplodedNode *Pred,
ProgramStateRef state,
bool GenSink) {
@@ -257,32 +263,31 @@
case OMF_retain:
case OMF_self: {
// These methods return their receivers.
- const Expr *ReceiverE = msg.getInstanceReceiver();
- if (ReceiverE)
- ReturnValue = state->getSVal(ReceiverE, Pred->getLocationContext());
+ ReturnValue = msg.getReceiverSVal();
break;
}
}
+ const LocationContext *LCtx = Pred->getLocationContext();
+ unsigned BlockCount = currentBuilderContext->getCurrentBlockCount();
+
// If we failed to figure out the return value, use a conjured value instead.
if (ReturnValue.isUnknown()) {
SValBuilder &SVB = getSValBuilder();
- QualType ResultTy = msg.getResultType(getContext());
- unsigned Count = currentBuilderContext->getCurrentBlockCount();
+ QualType ResultTy = msg.getResultType();
const Expr *CurrentE = cast<Expr>(currentStmt);
- const LocationContext *LCtx = Pred->getLocationContext();
- ReturnValue = SVB.getConjuredSymbolVal(NULL, CurrentE, LCtx, ResultTy, Count);
+ ReturnValue = SVB.getConjuredSymbolVal(NULL, CurrentE, LCtx, ResultTy,
+ BlockCount);
}
// Bind the return value.
- const LocationContext *LCtx = Pred->getLocationContext();
state = state->BindExpr(currentStmt, LCtx, ReturnValue);
// Invalidate the arguments (and the receiver)
- state = invalidateArguments(state, CallOrObjCMessage(msg, state, LCtx), LCtx);
+ state = msg.invalidateRegions(BlockCount, state);
// And create the new node.
- Bldr.generateNode(msg.getMessageExpr(), Pred, state, GenSink);
+ Bldr.generateNode(currentStmt, Pred, state, GenSink);
assert(Bldr.hasGeneratedNodes());
}
Removed: cfe/branches/tooling/lib/StaticAnalyzer/Core/ObjCMessage.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ObjCMessage.cpp?rev=159662&view=auto
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ObjCMessage.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ObjCMessage.cpp (removed)
@@ -1,175 +0,0 @@
-//===- ObjCMessage.cpp - Wrapper for ObjC messages and dot syntax -*- 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 ObjCMessage which serves as a common wrapper for ObjC
-// message expressions or implicit messages for loading/storing ObjC properties.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
-#include "clang/AST/DeclCXX.h"
-
-using namespace clang;
-using namespace ento;
-
-QualType CallOrObjCMessage::getResultType(ASTContext &ctx) const {
- QualType resultTy;
- bool isLVal = false;
-
- if (isObjCMessage()) {
- resultTy = Msg.getResultType(ctx);
- } else if (const CXXConstructExpr *Ctor =
- CallE.dyn_cast<const CXXConstructExpr *>()) {
- resultTy = Ctor->getType();
- } else {
- const CallExpr *FunctionCall = CallE.get<const CallExpr *>();
-
- isLVal = FunctionCall->isGLValue();
- const Expr *Callee = FunctionCall->getCallee();
- if (const FunctionDecl *FD = State->getSVal(Callee, LCtx).getAsFunctionDecl())
- resultTy = FD->getResultType();
- else
- resultTy = FunctionCall->getType();
- }
-
- if (isLVal)
- resultTy = ctx.getPointerType(resultTy);
-
- return resultTy;
-}
-
-SVal CallOrObjCMessage::getFunctionCallee() const {
- assert(isFunctionCall());
- assert(!isCXXCall());
- const Expr *Fun = CallE.get<const CallExpr *>()->getCallee()->IgnoreParens();
- return State->getSVal(Fun, LCtx);
-}
-
-SVal CallOrObjCMessage::getCXXCallee() const {
- assert(isCXXCall());
- const CallExpr *ActualCall = CallE.get<const CallExpr *>();
- const Expr *callee =
- cast<CXXMemberCallExpr>(ActualCall)->getImplicitObjectArgument();
-
- // FIXME: Will eventually need to cope with member pointers. This is
- // a limitation in getImplicitObjectArgument().
- if (!callee)
- return UnknownVal();
-
- return State->getSVal(callee, LCtx);
-}
-
-SVal
-CallOrObjCMessage::getInstanceMessageReceiver(const LocationContext *LC) const {
- assert(isObjCMessage());
- return Msg.getInstanceReceiverSVal(State, LC);
-}
-
-const Decl *CallOrObjCMessage::getDecl() const {
- if (isCXXCall()) {
- const CXXMemberCallExpr *CE =
- cast<CXXMemberCallExpr>(CallE.dyn_cast<const CallExpr *>());
- assert(CE);
- return CE->getMethodDecl();
- } else if (isObjCMessage()) {
- return Msg.getMethodDecl();
- } else if (isFunctionCall()) {
- // In case of a C style call, use the path sensitive information to find
- // the function declaration.
- SVal CalleeVal = getFunctionCallee();
- return CalleeVal.getAsFunctionDecl();
- }
- return 0;
-}
-
-bool CallOrObjCMessage::isCallbackArg(unsigned Idx, const Type *T) const {
- // If the parameter is 0, it's harmless.
- if (getArgSVal(Idx).isZeroConstant())
- return false;
-
- // If a parameter is a block or a callback, assume it can modify pointer.
- if (T->isBlockPointerType() ||
- T->isFunctionPointerType() ||
- T->isObjCSelType())
- return true;
-
- // Check if a callback is passed inside a struct (for both, struct passed by
- // reference and by value). Dig just one level into the struct for now.
- if (const PointerType *PT = dyn_cast<PointerType>(T))
- T = PT->getPointeeType().getTypePtr();
-
- if (const RecordType *RT = T->getAsStructureType()) {
- const RecordDecl *RD = RT->getDecl();
- for (RecordDecl::field_iterator I = RD->field_begin(),
- E = RD->field_end(); I != E; ++I ) {
- const Type *FieldT = I->getType().getTypePtr();
- if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
- return true;
- }
- }
- return false;
-}
-
-bool CallOrObjCMessage::hasNonZeroCallbackArg() const {
- unsigned NumOfArgs = getNumArgs();
-
- // Process ObjC message first.
- if (!CallE) {
- const ObjCMethodDecl *D = Msg.getMethodDecl();
- unsigned Idx = 0;
- for (ObjCMethodDecl::param_const_iterator I = D->param_begin(),
- E = D->param_end(); I != E; ++I, ++Idx) {
- if (NumOfArgs <= Idx)
- break;
-
- if (isCallbackArg(Idx, (*I)->getType().getTypePtr()))
- return true;
- }
- return false;
- }
-
- // Else, assume we are dealing with a Function call.
- const FunctionDecl *FD = 0;
- if (const CXXConstructExpr *Ctor =
- CallE.dyn_cast<const CXXConstructExpr *>())
- FD = Ctor->getConstructor();
-
- const CallExpr * CE = CallE.get<const CallExpr *>();
- FD = dyn_cast_or_null<FunctionDecl>(CE->getCalleeDecl());
-
- // If calling using a function pointer, assume the function does not
- // have a callback. TODO: We could check the types of the arguments here.
- if (!FD)
- return false;
-
- unsigned Idx = 0;
- for (FunctionDecl::param_const_iterator I = FD->param_begin(),
- E = FD->param_end(); I != E; ++I, ++Idx) {
- if (NumOfArgs <= Idx)
- break;
-
- if (isCallbackArg(Idx, (*I)->getType().getTypePtr()))
- return true;
- }
- return false;
-}
-
-bool CallOrObjCMessage::isCFCGAllowingEscape(StringRef FName) {
- if (!FName.startswith("CF") && !FName.startswith("CG"))
- return false;
-
- return StrInStrNoCase(FName, "InsertValue") != StringRef::npos ||
- StrInStrNoCase(FName, "AddValue") != StringRef::npos ||
- StrInStrNoCase(FName, "SetValue") != StringRef::npos ||
- StrInStrNoCase(FName, "WithData") != StringRef::npos ||
- StrInStrNoCase(FName, "AppendValue") != StringRef::npos ||
- StrInStrNoCase(FName, "SetAttribute") != StringRef::npos;
-}
-
-
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ProgramState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ProgramState.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ProgramState.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ProgramState.cpp Tue Jul 3 11:18:37 2012
@@ -157,7 +157,7 @@
const Expr *E, unsigned Count,
const LocationContext *LCtx,
StoreManager::InvalidatedSymbols *IS,
- const CallOrObjCMessage *Call) const {
+ const CallEvent *Call) const {
if (!IS) {
StoreManager::InvalidatedSymbols invalidated;
return invalidateRegionsImpl(Regions, E, Count, LCtx,
@@ -171,7 +171,7 @@
const Expr *E, unsigned Count,
const LocationContext *LCtx,
StoreManager::InvalidatedSymbols &IS,
- const CallOrObjCMessage *Call) const {
+ const CallEvent *Call) const {
ProgramStateManager &Mgr = getStateManager();
SubEngine* Eng = Mgr.getOwningEngine();
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp Tue Jul 3 11:18:37 2012
@@ -20,7 +20,7 @@
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Basic/TargetInfo.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
@@ -252,7 +252,7 @@
const Expr *E, unsigned Count,
const LocationContext *LCtx,
InvalidatedSymbols &IS,
- const CallOrObjCMessage *Call,
+ const CallEvent *Call,
InvalidatedRegions *Invalidated);
public: // Made public for helper classes.
@@ -790,7 +790,7 @@
const Expr *Ex, unsigned Count,
const LocationContext *LCtx,
InvalidatedSymbols &IS,
- const CallOrObjCMessage *Call,
+ const CallEvent *Call,
InvalidatedRegions *Invalidated) {
invalidateRegionsWorker W(*this, StateMgr,
RegionStoreManager::GetRegionBindings(store),
Modified: cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Tue Jul 3 11:18:37 2012
@@ -22,6 +22,7 @@
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/CallGraph.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Checkers/LocalCheckers.h"
@@ -347,7 +348,7 @@
for (llvm::SmallVector<CallGraphNode*, 24>::reverse_iterator
TI = TopLevelFunctions.rbegin(), TE = TopLevelFunctions.rend();
TI != TE; ++TI)
- BFSQueue.push_front(*TI);
+ BFSQueue.push_back(*TI);
// BFS over all of the functions, while skipping the ones inlined into
// the previously processed functions. Use external Visited set, which is
@@ -357,6 +358,13 @@
CallGraphNode *N = BFSQueue.front();
BFSQueue.pop_front();
+ // Push the children into the queue.
+ for (CallGraphNode::const_iterator CI = N->begin(),
+ CE = N->end(); CI != CE; ++CI) {
+ if (!Visited.count(*CI))
+ BFSQueue.push_back(*CI);
+ }
+
// Skip the functions which have been processed already or previously
// inlined.
if (Visited.count(N))
@@ -377,12 +385,6 @@
Visited.insert(VN);
}
Visited.insert(N);
-
- // Push the children into the queue.
- for (CallGraphNode::const_iterator CI = N->begin(),
- CE = N->end(); CI != CE; ++CI) {
- BFSQueue.push_front(*CI);
- }
}
}
@@ -521,6 +523,10 @@
if (!Mgr->getCFG(D))
return;
+ // See if the LiveVariables analysis scales.
+ if (!Mgr->getAnalysisDeclContext(D)->getAnalysis<RelaxedLiveVariables>())
+ return;
+
ExprEngine Eng(*Mgr, ObjCGCEnabled, VisitedCallees, &FunctionSummaries);
// Set the graph auditor.
Modified: cfe/branches/tooling/test/Analysis/delegates.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/delegates.m?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/delegates.m (original)
+++ cfe/branches/tooling/test/Analysis/delegates.m Tue Jul 3 11:18:37 2012
@@ -96,13 +96,12 @@
@implementation test_6062730
- (void) foo {
- NSString *str = [[NSString alloc] init];
+ NSString *str = [[NSString alloc] init]; // no-warning
[test_6062730 performSelectorOnMainThread:@selector(postNotification:) withObject:str waitUntilDone:1];
}
- (void) bar {
- NSString *str = [[NSString alloc] init]; // expected-warning{{leak}}
- // FIXME: We need to resolve [self class] to 'test_6062730'.
+ NSString *str = [[NSString alloc] init]; // no-warning
[[self class] performSelectorOnMainThread:@selector(postNotification:) withObject:str waitUntilDone:1];
}
Modified: cfe/branches/tooling/test/Analysis/malloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/malloc.c?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/malloc.c (original)
+++ cfe/branches/tooling/test/Analysis/malloc.c Tue Jul 3 11:18:37 2012
@@ -717,6 +717,18 @@
return f; // expected-warning{{leak}}
}
+static int readNothing(void *_ctx, char *buf, int size) {
+ return 0;
+}
+FILE *useFunOpenReadNoRelease() {
+ void *ctx = malloc(sizeof(int));
+ FILE *f = funopen(ctx, readNothing, 0, 0, 0);
+ if (f == 0) {
+ free(ctx);
+ }
+ return f; // expected-warning{{leak}}
+}
+
// Test setbuf, setvbuf.
int my_main_no_warning() {
char *p = malloc(100);
Modified: cfe/branches/tooling/test/Analysis/misc-ps-region-store.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/misc-ps-region-store.m?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/misc-ps-region-store.m (original)
+++ cfe/branches/tooling/test/Analysis/misc-ps-region-store.m Tue Jul 3 11:18:37 2012
@@ -673,7 +673,7 @@
builder = ^(id object) {
id x;
if (object) {
- builder(x); // expected-warning{{Function call argument is an uninitialized value}}
+ builder(x); // expected-warning{{Block call argument is an uninitialized value}}
}
};
builder(target);
Modified: cfe/branches/tooling/test/Analysis/new.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/new.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/new.cpp (original)
+++ cfe/branches/tooling/test/Analysis/new.cpp Tue Jul 3 11:18:37 2012
@@ -49,6 +49,16 @@
return y; // no-warning
}
+void *operator new(size_t, void *, void *);
+void *testCustomNewMalloc() {
+ int *x = (int *)malloc(sizeof(int));
+
+ // Should be no-warning (the custom allocator could have freed x).
+ void *y = new (0, x) int; // no-warning
+
+ return y;
+}
+
//--------------------------------
// Incorrectly-modelled behavior
@@ -69,14 +79,3 @@
clang_analyzer_eval(*n == 3); // expected-warning{{UNKNOWN}}
}
-
-void *operator new(size_t, void *, void *);
-void *testCustomNewMalloc() {
- int *x = (int *)malloc(sizeof(int));
-
- // Should be no-warning (the custom allocator could have freed x).
- void *y = new (0, x) int; // expected-warning{{leak of memory pointed to by 'x'}}
-
- return y;
-}
-
Modified: cfe/branches/tooling/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m (original)
+++ cfe/branches/tooling/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m Tue Jul 3 11:18:37 2012
@@ -80,11 +80,11 @@
int marker(void) { // control reaches end of non-void function
}
-// CHECK-darwin8: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage
// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
-// CHECK-darwin8: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage
// CHECK-darwin8: warning: The receiver of message 'unsignedLongLongM' is nil and returns a value of type 'unsigned long long' that will be garbage
+// CHECK-darwin8: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage
// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
+// CHECK-darwin8: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage
// CHECK-darwin9-NOT: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
// CHECK-darwin9-NOT: warning: The receiver of message 'unsignedLongLongM' is nil and returns a value of type 'unsigned long long' that will be garbage
Modified: cfe/branches/tooling/test/Analysis/traversal-algorithm.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/traversal-algorithm.mm?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/traversal-algorithm.mm (original)
+++ cfe/branches/tooling/test/Analysis/traversal-algorithm.mm Tue Jul 3 11:18:37 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpTraversal -std=c++11 %s | FileCheck -check-prefix=DFS %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpTraversal -analyzer-max-loop 4 -std=c++11 %s | FileCheck -check-prefix=DFS %s
int a();
int b();
@@ -23,43 +23,6 @@
work();
}
-// This ordering assumes that true cases happen before the false cases.
-
-// BFS: 10 IfStmt
-// BFS-NEXT: 11 IfStmt
-// BFS-NEXT: 16 IfStmt
-// BFS-NEXT: 22 IfStmt
-// BFS-NEXT: 22 IfStmt
-// BFS-NEXT: 22 IfStmt
-// BFS-NEXT: 22 IfStmt
-// BFS-NEXT: --END PATH--
-// BFS-NEXT: --END PATH--
-// BFS-NEXT: --END PATH--
-// BFS-NEXT: --END PATH--
-// BFS-NEXT: --END PATH--
-// BFS-NEXT: --END PATH--
-// BFS-NEXT: --END PATH--
-// BFS-NEXT: --END PATH--
-
-// And this ordering assumes that false cases happen before the true cases.
-
-// DFS: 10 IfStmt
-// DFS-NEXT: 16 IfStmt
-// DFS-NEXT: 22 IfStmt
-// DFS-NEXT: --END PATH--
-// DFS-NEXT: --END PATH--
-// DFS-NEXT: 22 IfStmt
-// DFS-NEXT: --END PATH--
-// DFS-NEXT: --END PATH--
-// DFS-NEXT: 11 IfStmt
-// DFS-NEXT: 22 IfStmt
-// DFS-NEXT: --END PATH--
-// DFS-NEXT: --END PATH--
-// DFS-NEXT: 22 IfStmt
-// DFS-NEXT: --END PATH--
-// DFS-NEXT: --END PATH--
-
-
void testLoops(id input) {
while (a()) {
work();
@@ -85,13 +48,166 @@
}
}
-// BFS: 64 WhileStmt
-// BFS: 70 ForStmt
-// BFS-NOT-NEXT: ObjCForCollectionStmt
-// BFS: 74 ObjCForCollectionStmt
-// BFS: 81 CXXForRangeStmt
-
-// DFS: 64 While
-// DFS-NEXT: 70 ForStmt
-// DFS-NEXT: 74 ObjCForCollectionStmt
-// DFS-NEXT: 81 CXXForRangeStmt
+// This ordering assumes that false cases happen before the true cases.
+
+// DFS:27 WhileStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:27 WhileStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:27 WhileStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:27 WhileStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:33 ForStmt
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:44 CXXForRangeStmt
+// DFS-next:--END PATH--
+// DFS-next:37 ObjCForCollectionStmt
+// DFS-next:10 IfStmt
+// DFS-next:16 IfStmt
+// DFS-next:22 IfStmt
+// DFS-next:--END PATH--
+// DFS-next:--END PATH--
+// DFS-next:22 IfStmt
+// DFS-next:--END PATH--
+// DFS-next:--END PATH--
+// DFS-next:11 IfStmt
+// DFS-next:22 IfStmt
+// DFS-next:--END PATH--
+// DFS-next:--END PATH--
+// DFS-next:22 IfStmt
+// DFS-next:--END PATH--
+// DFS-next:--END PATH--
+
Modified: cfe/branches/tooling/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CMakeLists.txt?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/CMakeLists.txt (original)
+++ cfe/branches/tooling/test/CMakeLists.txt Tue Jul 3 11:18:37 2012
@@ -34,13 +34,19 @@
clang-check
llvm-dis llc opt FileCheck count not
)
+ set(CLANG_TEST_PARAMS
+ clang_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+ )
+
if(LLVM_INCLUDE_TESTS)
list(APPEND CLANG_TEST_DEPS ClangUnitTests)
+ list(APPEND CLANG_TEST_PARAMS
+ clang_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
+ )
endif()
add_lit_testsuite(check-clang "Running the Clang regression tests"
${CMAKE_CURRENT_BINARY_DIR}
- PARAMS clang_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
- clang_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
+ PARAMS ${CLANG_TEST_PARAMS}
DEPENDS ${CLANG_TEST_DEPS}
ARGS ${CLANG_TEST_EXTRA_ARGS}
)
@@ -51,7 +57,7 @@
include(FindPythonInterp)
if(PYTHONINTERP_FOUND)
if( LLVM_MAIN_SRC_DIR )
- set(LIT "${LLVM_SOURCE_DIR}/utils/lit/lit.py")
+ set(LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py")
else()
set(LIT "${PATH_TO_LLVM_BUILD}/bin/${CMAKE_CFG_INTDIR}/llvm-lit")
# Installed LLVM does not contain ${CMAKE_CFG_INTDIR} in paths.
@@ -67,7 +73,6 @@
COMMAND ${PYTHON_EXECUTABLE}
${LIT}
--param clang_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
- --param clang_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
--param build_config=${CMAKE_CFG_INTDIR}
--param build_mode=${RUNTIME_BUILD_MODE}
${LIT_ARGS}
@@ -83,5 +88,6 @@
endif()
# Add a legacy target spelling: clang-test
-add_custom_target(clang-test DEPENDS check-clang)
+add_custom_target(clang-test)
+add_dependencies(clang-test check-clang)
set_target_properties(clang-test PROPERTIES FOLDER "Clang tests")
Modified: cfe/branches/tooling/test/CodeGen/block-byref-aggr.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGen/block-byref-aggr.c?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGen/block-byref-aggr.c (original)
+++ cfe/branches/tooling/test/CodeGen/block-byref-aggr.c Tue Jul 3 11:18:37 2012
@@ -1,17 +1,66 @@
// RUN: %clang_cc1 %s -emit-llvm -o - -fblocks -triple x86_64-apple-darwin10 | FileCheck %s
-// rdar://9309454
-typedef struct { int v; } RetType;
+// CHECK: [[AGG:%.*]] = type { i32 }
+typedef struct { int v; } Agg;
+Agg makeAgg(void);
-RetType func();
+// When assigning into a __block variable, ensure that we compute that
+// address *after* evaluating the RHS when the RHS has the capacity to
+// cause a block copy. rdar://9309454
+void test0() {
+ __block Agg a = {100};
-int main () {
- __attribute__((__blocks__(byref))) RetType a = {100};
+ a = makeAgg();
+}
+// CHECK: define void @test0()
+// CHECK: [[A:%.*]] = alloca [[BYREF:%.*]], align 8
+// CHECK-NEXT: [[TEMP:%.*]] = alloca [[AGG]], align 4
+// CHECK: [[RESULT:%.*]] = call i32 @makeAgg()
+// CHECK-NEXT: [[T0:%.*]] = getelementptr [[AGG]]* [[TEMP]], i32 0, i32 0
+// CHECK-NEXT: store i32 [[RESULT]], i32* [[T0]]
+// Check that we properly assign into the forwarding pointer.
+// CHECK-NEXT: [[A_FORWARDING:%.*]] = getelementptr inbounds [[BYREF]]* [[A]], i32 0, i32 1
+// CHECK-NEXT: [[T0:%.*]] = load [[BYREF]]** [[A_FORWARDING]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[BYREF]]* [[T0]], i32 0, i32 4
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[AGG]]* [[T1]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[AGG]]* [[TEMP]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T2]], i8* [[T3]], i64 4, i32 4, i1 false)
+// Verify that there's nothing else significant in the function.
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[BYREF]]* [[A]] to i8*
+// CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
+// CHECK-NEXT: ret void
- a = func();
+// When chaining assignments into __block variables, make sure we
+// propagate the actual value into the outer variable.
+// rdar://11757470
+void test1() {
+ __block Agg a, b;
+ a = b = makeAgg();
}
-// CHECK: [[C1:%.*]] = call i32 (...)* @func()
-// CHECK-NEXT: [[CO:%.*]] = getelementptr
-// CHECK-NEXT: store i32 [[C1]], i32* [[CO]]
-// CHECK-NEXT: [[FORWARDING:%.*]] = getelementptr inbounds [[BR:%.*]]* [[A:%.*]], i32 0, i32 1
-// CHECK-NEXT: [[O:%.*]] = load [[BR]]** [[FORWARDING]]
+// CHECK: define void @test1()
+// CHECK: [[A:%.*]] = alloca [[A_BYREF:%.*]], align 8
+// CHECK-NEXT: [[B:%.*]] = alloca [[B_BYREF:%.*]], align 8
+// CHECK-NEXT: [[TEMP:%.*]] = alloca [[AGG]], align 4
+// CHECK: [[RESULT:%.*]] = call i32 @makeAgg()
+// CHECK-NEXT: [[T0:%.*]] = getelementptr [[AGG]]* [[TEMP]], i32 0, i32 0
+// CHECK-NEXT: store i32 [[RESULT]], i32* [[T0]]
+// Check that we properly assign into the forwarding pointer, first for b:
+// CHECK-NEXT: [[B_FORWARDING:%.*]] = getelementptr inbounds [[B_BYREF]]* [[B]], i32 0, i32 1
+// CHECK-NEXT: [[T0:%.*]] = load [[B_BYREF]]** [[B_FORWARDING]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[B_BYREF]]* [[T0]], i32 0, i32 4
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[AGG]]* [[T1]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[AGG]]* [[TEMP]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T2]], i8* [[T3]], i64 4, i32 4, i1 false)
+// Then for 'a':
+// CHECK-NEXT: [[A_FORWARDING:%.*]] = getelementptr inbounds [[A_BYREF]]* [[A]], i32 0, i32 1
+// CHECK-NEXT: [[T0:%.*]] = load [[A_BYREF]]** [[A_FORWARDING]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A_BYREF]]* [[T0]], i32 0, i32 4
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[AGG]]* [[T1]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[AGG]]* [[TEMP]] to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T2]], i8* [[T3]], i64 4, i32 4, i1 false)
+// Verify that there's nothing else significant in the function.
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[B_BYREF]]* [[B]] to i8*
+// CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[A_BYREF]]* [[A]] to i8*
+// CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
+// CHECK-NEXT: ret void
Modified: cfe/branches/tooling/test/CodeGen/bmi-builtins.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGen/bmi-builtins.c?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGen/bmi-builtins.c (original)
+++ cfe/branches/tooling/test/CodeGen/bmi-builtins.c Tue Jul 3 11:18:37 2012
@@ -5,9 +5,9 @@
#include <x86intrin.h>
-unsigned short test__tzcnt16(unsigned short __X) {
+unsigned short test__tzcnt_u16(unsigned short __X) {
// CHECK: @llvm.cttz.i16
- return __tzcnt16(__X);
+ return __tzcnt_u16(__X);
}
unsigned int test__andn_u32(unsigned int __X, unsigned int __Y) {
@@ -39,9 +39,9 @@
return __blsr_u32(__X);
}
-unsigned int test_tzcnt32(unsigned int __X) {
+unsigned int test_tzcnt_u32(unsigned int __X) {
// CHECK: @llvm.cttz.i32
- return __tzcnt32(__X);
+ return __tzcnt_u32(__X);
}
unsigned long long test__andn_u64(unsigned long __X, unsigned long __Y) {
@@ -73,7 +73,7 @@
return __blsr_u64(__X);
}
-unsigned long long test__tzcnt64(unsigned long long __X) {
+unsigned long long test__tzcnt_u64(unsigned long long __X) {
// CHECK: @llvm.cttz.i64
- return __tzcnt64(__X);
+ return __tzcnt_u64(__X);
}
Modified: cfe/branches/tooling/test/CodeGenCXX/inline-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/inline-functions.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/inline-functions.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/inline-functions.cpp Tue Jul 3 11:18:37 2012
@@ -53,3 +53,17 @@
c.func();
}
}
+
+// PR13252
+namespace test2 {
+ struct A;
+ void f(const A& a);
+ struct A {
+ friend void f(const A& a) { }
+ };
+ void g() {
+ A a;
+ f(a);
+ }
+ // CHECK: define linkonce_odr void @_ZN5test21fERKNS_1AE
+}
Modified: cfe/branches/tooling/test/Driver/crash-report.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Driver/crash-report.c?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/Driver/crash-report.c (original)
+++ cfe/branches/tooling/test/Driver/crash-report.c Tue Jul 3 11:18:37 2012
@@ -1,7 +1,13 @@
-// RUN: %clang -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: rm -f %T/crash-report-*.c %T/crash-report-*.sh
+// RUN: TMP=%T %clang -fsyntax-only %s -DFOO=BAR 2>&1 | FileCheck %s
+// RUN: FileCheck --check-prefix=CHECKSRC %s < %T/crash-report-*.c
+// RUN: FileCheck --check-prefix=CHECKSH %s < %T/crash-report-*.sh
// REQUIRES: crash-recovery
// XFAIL: mingw32,win32
#pragma clang __debug parser_crash
// CHECK: Preprocessed source(s) and associated run script(s) are located at:
-// CHECK-NEXT: {{.*}}: note: diagnostic msg: {{.*}}.c
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.c
+FOO
+// CHECKSRC: FOO
+// CHECKSH: -D FOO=BAR
Modified: cfe/branches/tooling/test/Misc/warning-flags.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Misc/warning-flags.c?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/Misc/warning-flags.c (original)
+++ cfe/branches/tooling/test/Misc/warning-flags.c Tue Jul 3 11:18:37 2012
@@ -17,7 +17,7 @@
The list of warnings below should NEVER grow. It should gradually shrink to 0.
-CHECK: Warnings without flags (230):
+CHECK: Warnings without flags (229):
CHECK-NEXT: ext_anonymous_struct_union_qualified
CHECK-NEXT: ext_binary_literal
CHECK-NEXT: ext_cast_fn_obj
@@ -141,7 +141,6 @@
CHECK-NEXT: warn_excess_initializers
CHECK-NEXT: warn_excess_initializers_in_char_array_initializer
CHECK-NEXT: warn_expected_qualified_after_typename
-CHECK-NEXT: warn_extern_init
CHECK-NEXT: warn_extraneous_char_constant
CHECK-NEXT: warn_fe_cc_log_diagnostics_failure
CHECK-NEXT: warn_fe_cc_print_header_failure
Modified: cfe/branches/tooling/test/Parser/declarators.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Parser/declarators.c?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/Parser/declarators.c (original)
+++ cfe/branches/tooling/test/Parser/declarators.c Tue Jul 3 11:18:37 2012
@@ -107,3 +107,8 @@
int x = 4+(5-12)); // expected-error {{extraneous ')' before ';'}}
}
+enum E1 { e1 }: // expected-error {{expected ';'}}
+struct EnumBitfield {
+ enum E2 { e2 } : 4; // ok
+ struct S { int n; }: // expected-error {{expected ';'}}
+};
Modified: cfe/branches/tooling/test/Sema/uninit-variables.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/uninit-variables.c?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/uninit-variables.c (original)
+++ cfe/branches/tooling/test/Sema/uninit-variables.c Tue Jul 3 11:18:37 2012
@@ -466,3 +466,22 @@
k = produce();
}
}
+
+typedef char jmp_buf[256];
+extern int setjmp(jmp_buf env); // implicitly returns_twice
+
+void do_stuff_and_longjmp(jmp_buf env, int *result) __attribute__((noreturn));
+
+int returns_twice() {
+ int a; // expected-note {{initialize}}
+ if (!a) { // expected-warning {{variable 'a' is uninitialized}}
+ jmp_buf env;
+ int b;
+ if (setjmp(env) == 0) {
+ do_stuff_and_longjmp(env, &b);
+ } else {
+ a = b; // no warning
+ }
+ }
+ return a;
+}
Removed: cfe/branches/tooling/test/Sema/warn-self-assign-memvar.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/warn-self-assign-memvar.mm?rev=159662&view=auto
==============================================================================
--- cfe/branches/tooling/test/Sema/warn-self-assign-memvar.mm (original)
+++ cfe/branches/tooling/test/Sema/warn-self-assign-memvar.mm (removed)
@@ -1,66 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-class S {
- public:
- int a_;
- void s(int a) {
- a_ = a_; // expected-warning {{assigning member variable to itself}}
-
- // Don't really care about this one either way.
- this->a_ = a_; // expected-warning {{assigning member variable to itself}}
-
- a_ += a_; // Shouldn't warn.
- }
-};
-
-void f0(S* s) {
- // Would be nice to have, but not important.
- s->a_ = s->a_;
-}
-
-void f1(S* s, S* t) {
- // Shouldn't warn.
- t->a_ = s->a_;
-}
-
-struct T {
- S* s_;
-};
-
-void f2(T* t) {
- // Would be nice to have, but even less important.
- t->s_->a_ = t->s_->a_;
-}
-
-void f3(T* t, T* t2) {
- // Shouldn't warn.
- t2->s_->a_ = t->s_->a_;
-}
-
-void f4(int i) {
- // This is a common pattern to silence "parameter unused". Shouldn't warn.
- i = i;
-
- int j = 0;
- j = j; // Likewise.
-}
-
- at interface I {
- int a_;
-}
- at end
-
- at implementation I
-- (void)setA:(int)a {
- a_ = a_; // expected-warning {{assigning instance variable to itself}}
-}
-
-- (void)foo:(I*)i {
- // Don't care much about this warning.
- i->a_ = i->a_; // expected-warning {{assigning instance variable to itself}}
-
- // Shouldn't warn.
- a_ = i->a_;
- i->a_ = a_;
-}
- at end
Modified: cfe/branches/tooling/test/SemaCXX/PR9460.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/PR9460.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/PR9460.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/PR9460.cpp Tue Jul 3 11:18:37 2012
@@ -8,11 +8,11 @@
basic_string(aT*);
};
-struct runtime_error{
- runtime_error(
+struct runtime_error{ // expected-note{{candidate constructor}}
+ runtime_error( // expected-note{{candidate constructor}}
basic_string<char> struct{ // expected-error {{cannot combine with previous 'type-name' declaration specifier}}
a(){ // expected-error {{requires a type specifier}}
- runtime_error(0);
+ runtime_error(0); // expected-error{{no matching conversion for functional-style cast from 'int' to 'runtime_error'}}
}
}
);
Modified: cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp Tue Jul 3 11:18:37 2012
@@ -1270,6 +1270,31 @@
}
}
+// Constructors can be implicitly constexpr, even for a non-literal type.
+namespace ImplicitConstexpr {
+ struct Q { Q() = default; Q(const Q&) = default; Q(Q&&) = default; ~Q(); }; // expected-note 3{{here}}
+ struct R { constexpr R(); constexpr R(const R&); constexpr R(R&&); ~R(); };
+ struct S { R r; }; // expected-note 3{{here}}
+ struct T { T(const T&); T(T &&); ~T(); };
+ struct U { T t; }; // expected-note 3{{here}}
+ static_assert(!__is_literal_type(Q), "");
+ static_assert(!__is_literal_type(R), "");
+ static_assert(!__is_literal_type(S), "");
+ static_assert(!__is_literal_type(T), "");
+ static_assert(!__is_literal_type(U), "");
+ struct Test {
+ friend Q::Q() noexcept; // expected-error {{follows constexpr}}
+ friend Q::Q(Q&&) noexcept; // expected-error {{follows constexpr}}
+ friend Q::Q(const Q&) noexcept; // expected-error {{follows constexpr}}
+ friend S::S() noexcept; // expected-error {{follows constexpr}}
+ friend S::S(S&&) noexcept; // expected-error {{follows constexpr}}
+ friend S::S(const S&) noexcept; // expected-error {{follows constexpr}}
+ friend constexpr U::U() noexcept; // expected-error {{follows non-constexpr}}
+ friend constexpr U::U(U&&) noexcept; // expected-error {{follows non-constexpr}}
+ friend constexpr U::U(const U&) noexcept; // expected-error {{follows non-constexpr}}
+ };
+}
+
// Indirectly test that an implicit lvalue to xvalue conversion performed for
// an NRVO move operation isn't implemented as CK_LValueToRValue.
namespace PR12826 {
Modified: cfe/branches/tooling/test/SemaCXX/warn-thread-safety-analysis.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/warn-thread-safety-analysis.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/warn-thread-safety-analysis.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/warn-thread-safety-analysis.cpp Tue Jul 3 11:18:37 2012
@@ -2403,7 +2403,135 @@
} // end namespace ReleasableScopedLock
+namespace TrylockFunctionTest {
+class Foo {
+public:
+ Mutex mu1_;
+ Mutex mu2_;
+ bool c;
+ bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_);
+};
+bool Foo::lockBoth() {
+ if (!mu1_.TryLock())
+ return false;
+
+ mu2_.Lock();
+ if (!c) {
+ mu1_.Unlock();
+ mu2_.Unlock();
+ return false;
+ }
+
+ return true;
+}
+
+
+} // end namespace TrylockFunctionTest
+
+
+
+namespace DoubleLockBug {
+
+class Foo {
+public:
+ Mutex mu_;
+ int a GUARDED_BY(mu_);
+
+ void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
+};
+
+
+void Foo::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
+ a = 0;
+}
+
+};
+
+
+namespace UnlockBug {
+
+class Foo {
+public:
+ Mutex mutex_;
+
+ void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
+ mutex_.Unlock();
+ } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
+
+
+ void foo2() SHARED_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
+ mutex_.Unlock();
+ } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
+};
+
+} // end namespace UnlockBug
+
+
+namespace FoolishScopedLockableBug {
+
+class SCOPED_LOCKABLE WTF_ScopedLockable {
+public:
+ WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu);
+
+ // have to call release() manually;
+ ~WTF_ScopedLockable();
+
+ void release() UNLOCK_FUNCTION();
+};
+
+
+class Foo {
+ Mutex mu_;
+ int a GUARDED_BY(mu_);
+ bool c;
+
+ void doSomething();
+
+ void test1() {
+ WTF_ScopedLockable wtf(&mu_);
+ wtf.release();
+ }
+
+ void test2() {
+ WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
+ } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+
+ void test3() {
+ if (c) {
+ WTF_ScopedLockable wtf(&mu_);
+ wtf.release();
+ }
+ }
+
+ void test4() {
+ if (c) {
+ doSomething();
+ }
+ else {
+ WTF_ScopedLockable wtf(&mu_);
+ wtf.release();
+ }
+ }
+
+ void test5() {
+ if (c) {
+ WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
+ }
+ } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
+
+ void test6() {
+ if (c) {
+ doSomething();
+ }
+ else {
+ WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
+ }
+ } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
+};
+
+
+} // end namespace FoolishScopedLockableBug
Propchange: cfe/branches/tooling/test/SemaCXX/warn-unreachable.cpp
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Jul 3 11:18:37 2012
@@ -1,2 +1,2 @@
/cfe/branches/type-system-rewrite/test/SemaCXX/warn-unreachable.cpp:134693-134817
-/cfe/trunk/test/SemaCXX/warn-unreachable.cpp:121961,146581-159509
+/cfe/trunk/test/SemaCXX/warn-unreachable.cpp:121961,146581-159654
Modified: cfe/branches/tooling/test/SemaObjC/blocks.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/blocks.m?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/blocks.m (original)
+++ cfe/branches/tooling/test/SemaObjC/blocks.m Tue Jul 3 11:18:37 2012
@@ -76,8 +76,7 @@
// In C, enum constants have the type of the underlying integer type, not the
// enumeration they are part of. We pretend the constants have enum type when
-// inferring block return types, so that they can be mixed-and-matched with
-// other expressions of enum type.
+// they are mixed with other expressions of enum type.
enum CStyleEnum {
CSE_Value = 1
};
@@ -88,37 +87,32 @@
cse_block_t a;
// No warnings here.
- a = ^{ return CSE_Value; };
a = ^{ return getCSE(); };
a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
return 1;
};
+ a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
+ return CSE_Value;
+ };
// No warnings here.
- a = ^{ if (arg) return CSE_Value; else return CSE_Value; };
- a = ^{ if (arg) return getCSE(); else return getCSE(); };
a = ^{ if (arg) return CSE_Value; else return getCSE(); };
a = ^{ if (arg) return getCSE(); else return CSE_Value; };
- // Technically these two blocks should return 'int'.
- // The first case is easy to handle -- just don't cast the enum constant
- // to the enum type. However, the second guess would require going back
- // and REMOVING the cast from the first return statement, which isn't really
- // feasible (there may be more than one previous return statement with enum
- // type). For symmetry, we just treat them the same way.
+ // These two blocks actually return 'int'
a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
if (arg)
return 1;
else
- return CSE_Value; // expected-error {{return type 'enum CStyleEnum' must match previous return type 'int'}}
+ return CSE_Value;
};
- a = ^{
+ a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
if (arg)
return CSE_Value;
else
- return 1; // expected-error {{return type 'int' must match previous return type 'enum CStyleEnum'}}
+ return 1;
};
}
@@ -133,7 +127,6 @@
fte_block_t a;
// No warnings here.
- a = ^{ return FTE_Value; };
a = ^{ return getFTE(); };
// Since we fixed the underlying type of the enum, this is considered a
@@ -141,31 +134,29 @@
a = ^{
return 1U;
};
-
+ a = ^{
+ return FTE_Value;
+ };
+
// No warnings here.
a = ^{ if (arg) return FTE_Value; else return FTE_Value; };
a = ^{ if (arg) return getFTE(); else return getFTE(); };
a = ^{ if (arg) return FTE_Value; else return getFTE(); };
a = ^{ if (arg) return getFTE(); else return FTE_Value; };
- // Technically these two blocks should return 'unsigned'.
- // The first case is easy to handle -- just don't cast the enum constant
- // to the enum type. However, the second guess would require going back
- // and REMOVING the cast from the first return statement, which isn't really
- // feasible (there may be more than one previous return statement with enum
- // type). For symmetry, we just treat them the same way.
+ // These two blocks actually return 'unsigned'.
a = ^{
if (arg)
return 1U;
else
- return FTE_Value; // expected-error{{return type 'enum FixedTypeEnum' must match previous return type 'unsigned int'}}
+ return FTE_Value;
};
a = ^{
if (arg)
return FTE_Value;
else
- return 1U; // expected-error{{return type 'unsigned int' must match previous return type 'enum FixedTypeEnum'}}
+ return 1U;
};
}
@@ -181,22 +172,25 @@
typedef enum {
TDE_Value
} TypeDefEnum;
+TypeDefEnum getTDE();
typedef enum : short {
TDFTE_Value
} TypeDefFixedTypeEnum;
-
+TypeDefFixedTypeEnum getTDFTE();
typedef int (^int_block_t)();
typedef short (^short_block_t)();
-void testAnonymousEnumTypes() {
+void testAnonymousEnumTypes(int arg) {
int_block_t IB;
IB = ^{ return AnonymousValue; };
- IB = ^{ return TDE_Value; }; // expected-error {{incompatible block pointer types assigning to 'int_block_t' (aka 'int (^)()') from 'TypeDefEnum (^)(void)'}}
- IB = ^{ return CSE_Value; }; // expected-error {{incompatible block pointer types assigning to 'int_block_t' (aka 'int (^)()') from 'enum CStyleEnum (^)(void)'}}
+ IB = ^{ if (arg) return TDE_Value; else return getTDE(); }; // expected-error {{incompatible block pointer}}
+ IB = ^{ if (arg) return getTDE(); else return TDE_Value; }; // expected-error {{incompatible block pointer}}
+ // Since we fixed the underlying type of the enum, these are considered
+ // compatible block types anyway.
short_block_t SB;
SB = ^{ return FixedAnonymousValue; };
- // This is not an error anyway since the enum has a fixed underlying type.
- SB = ^{ return TDFTE_Value; };
+ SB = ^{ if (arg) return TDFTE_Value; else return getTDFTE(); };
+ SB = ^{ if (arg) return getTDFTE(); else return TDFTE_Value; };
}
Modified: cfe/branches/tooling/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/c-index-test/c-index-test.c?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/tools/c-index-test/c-index-test.c (original)
+++ cfe/branches/tooling/tools/c-index-test/c-index-test.c Tue Jul 3 11:18:37 2012
@@ -59,6 +59,8 @@
options &= ~CXTranslationUnit_CacheCompletionResults;
if (getenv("CINDEXTEST_SKIP_FUNCTION_BODIES"))
options |= CXTranslationUnit_SkipFunctionBodies;
+ if (getenv("CINDEXTEST_COMPLETION_BRIEF_COMMENTS"))
+ options |= CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
return options;
}
@@ -1220,6 +1222,8 @@
unsigned annotationCount;
enum CXCursorKind ParentKind;
CXString ParentName;
+ CXString BriefComment;
+ const char *BriefCommentCString;
fprintf(file, "%s:", clang_getCString(ks));
clang_disposeString(ks);
@@ -1271,6 +1275,14 @@
}
clang_disposeString(ParentName);
}
+
+ BriefComment = clang_getCompletionBriefComment(
+ completion_result->CompletionString);
+ BriefCommentCString = clang_getCString(BriefComment);
+ if (BriefCommentCString && *BriefCommentCString != '\0') {
+ fprintf(file, "(brief comment: %s)", BriefCommentCString);
+ }
+ clang_disposeString(BriefComment);
fprintf(file, "\n");
}
@@ -1383,6 +1395,8 @@
if (getenv("CINDEXTEST_CODE_COMPLETE_PATTERNS"))
completionOptions |= CXCodeComplete_IncludeCodePatterns;
+ if (getenv("CINDEXTEST_COMPLETION_BRIEF_COMMENTS"))
+ completionOptions |= CXCodeComplete_IncludeBriefComments;
if (timing_only)
input += strlen("-code-completion-timing=");
@@ -1600,6 +1614,9 @@
clang_disposeString(Spelling);
if (clang_Cursor_getObjCSelectorIndex(Cursor) != -1)
printf(" Selector index=%d",clang_Cursor_getObjCSelectorIndex(Cursor));
+ if (clang_Cursor_isDynamicCall(Cursor))
+ printf(" Dynamic-call");
+
if (completionString != NULL) {
printf("\nCompletion string: ");
print_completion_string(completionString, stdout);
Modified: cfe/branches/tooling/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/CIndex.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/CIndex.cpp (original)
+++ cfe/branches/tooling/tools/libclang/CIndex.cpp Tue Jul 3 11:18:37 2012
@@ -2523,6 +2523,8 @@
= (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
bool CacheCodeCompetionResults
= options & CXTranslationUnit_CacheCompletionResults;
+ bool IncludeBriefCommentsInCodeCompletion
+ = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
// Configure the diagnostics.
@@ -2607,6 +2609,7 @@
PrecompilePreamble,
TUKind,
CacheCodeCompetionResults,
+ IncludeBriefCommentsInCodeCompletion,
/*AllowPCHWithCompilerErrors=*/true,
SkipFunctionBodies,
&ErrUnit));
Modified: cfe/branches/tooling/tools/libclang/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/CIndexCodeCompletion.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/CIndexCodeCompletion.cpp (original)
+++ cfe/branches/tooling/tools/libclang/CIndexCodeCompletion.cpp Tue Jul 3 11:18:37 2012
@@ -227,6 +227,17 @@
*kind = CCStr->getParentContextKind();
return createCXString(CCStr->getParentContextName(), /*DupString=*/false);
}
+
+CXString
+clang_getCompletionBriefComment(CXCompletionString completion_string) {
+ CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
+
+ if (!CCStr)
+ return createCXString((const char *) NULL);
+
+ return createCXString(CCStr->getBriefComment(), /*DupString=*/false);
+}
+
/// \brief The CXCodeCompleteResults structure we allocate internally;
/// the client only sees the initial CXCodeCompleteResults structure.
@@ -509,9 +520,10 @@
SmallVector<CXCompletionResult, 16> StoredResults;
CXTranslationUnit *TU;
public:
- CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results,
+ CaptureCompletionResults(const CodeCompleteOptions &Opts,
+ AllocatedCXCodeCompleteResults &Results,
CXTranslationUnit *TranslationUnit)
- : CodeCompleteConsumer(true, false, true, false),
+ : CodeCompleteConsumer(Opts, false),
AllocatedResults(Results), CCTUInfo(Results.CodeCompletionAllocator),
TU(TranslationUnit) { }
~CaptureCompletionResults() { Finish(); }
@@ -524,7 +536,8 @@
for (unsigned I = 0; I != NumResults; ++I) {
CodeCompletionString *StoredCompletion
= Results[I].CreateCodeCompletionString(S, getAllocator(),
- getCodeCompletionTUInfo());
+ getCodeCompletionTUInfo(),
+ includeBriefComments());
CXCompletionResult R;
R.CursorKind = Results[I].CursorKind;
@@ -658,6 +671,7 @@
struct CXUnsavedFile *unsaved_files = CCAI->unsaved_files;
unsigned num_unsaved_files = CCAI->num_unsaved_files;
unsigned options = CCAI->options;
+ bool IncludeBriefComments = options & CXCodeComplete_IncludeBriefComments;
CCAI->result = 0;
#ifdef UDP_CODE_COMPLETION_LOGGER
@@ -699,13 +713,16 @@
Results->NumResults = 0;
// Create a code-completion consumer to capture the results.
- CaptureCompletionResults Capture(*Results, &TU);
+ CodeCompleteOptions Opts;
+ Opts.IncludeBriefComments = IncludeBriefComments;
+ CaptureCompletionResults Capture(Opts, *Results, &TU);
// Perform completion.
AST->CodeComplete(complete_filename, complete_line, complete_column,
RemappedFiles.data(), RemappedFiles.size(),
(options & CXCodeComplete_IncludeMacros),
(options & CXCodeComplete_IncludeCodePatterns),
+ IncludeBriefComments,
Capture,
*Results->Diag, Results->LangOpts, *Results->SourceMgr,
*Results->FileMgr, Results->Diagnostics,
Modified: cfe/branches/tooling/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/CXCursor.cpp?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/CXCursor.cpp (original)
+++ cfe/branches/tooling/tools/libclang/CXCursor.cpp Tue Jul 3 11:18:37 2012
@@ -1198,7 +1198,8 @@
= Result.CreateCodeCompletionString(unit->getASTContext(),
unit->getPreprocessor(),
unit->getCodeCompletionTUInfo().getAllocator(),
- unit->getCodeCompletionTUInfo());
+ unit->getCodeCompletionTUInfo(),
+ true);
return String;
}
}
@@ -1211,7 +1212,8 @@
= Result.CreateCodeCompletionString(unit->getASTContext(),
unit->getPreprocessor(),
unit->getCodeCompletionTUInfo().getAllocator(),
- unit->getCodeCompletionTUInfo());
+ unit->getCodeCompletionTUInfo(),
+ false);
return String;
}
return NULL;
@@ -1317,5 +1319,30 @@
pool.AvailableCursors.push_back(Vec);
}
-
+
+int clang_Cursor_isDynamicCall(CXCursor C) {
+ const Expr *E = 0;
+ if (clang_isExpression(C.kind))
+ E = getCursorExpr(C);
+ if (!E)
+ return 0;
+
+ if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E))
+ return MsgE->getReceiverKind() == ObjCMessageExpr::Instance;
+
+ const MemberExpr *ME = 0;
+ if (isa<MemberExpr>(E))
+ ME = cast<MemberExpr>(E);
+ else if (const CallExpr *CE = dyn_cast<CallExpr>(E))
+ ME = dyn_cast_or_null<MemberExpr>(CE->getCallee());
+
+ if (ME) {
+ if (const CXXMethodDecl *
+ MD = dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl()))
+ return MD->isVirtual() && !ME->hasQualifier();
+ }
+
+ return 0;
+}
+
} // end: extern "C"
Modified: cfe/branches/tooling/tools/libclang/libclang.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/libclang.exports?rev=159663&r1=159662&r2=159663&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/libclang.exports (original)
+++ cfe/branches/tooling/tools/libclang/libclang.exports Tue Jul 3 11:18:37 2012
@@ -12,6 +12,7 @@
clang_Cursor_getObjCSelectorIndex
clang_Cursor_getSpellingNameRange
clang_Cursor_getTranslationUnit
+clang_Cursor_isDynamicCall
clang_Cursor_isNull
clang_IndexAction_create
clang_IndexAction_dispose
@@ -71,6 +72,7 @@
clang_getClangVersion
clang_getCompletionAnnotation
clang_getCompletionAvailability
+clang_getCompletionBriefComment
clang_getCompletionChunkCompletionString
clang_getCompletionChunkKind
clang_getCompletionChunkText
More information about the llvm-branch-commits
mailing list